rb-appscript 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. data/CHANGES +17 -0
  2. data/README +1 -1
  3. data/TODO +0 -4
  4. data/doc/appscript-manual/01_introduction.html +3 -2
  5. data/doc/appscript-manual/02_aboutappscripting.html +4 -4
  6. data/doc/appscript-manual/03_quicktutorial.html +14 -12
  7. data/doc/appscript-manual/04_gettinghelp.html +1 -1
  8. data/doc/appscript-manual/06_classesandenums.html +3 -3
  9. data/doc/appscript-manual/07_applicationobjects.html +17 -16
  10. data/doc/appscript-manual/08_realvsgenericreferences.html +16 -16
  11. data/doc/appscript-manual/09_referenceforms.html +15 -15
  12. data/doc/appscript-manual/10_referenceexamples.html +28 -27
  13. data/doc/appscript-manual/11_applicationcommands.html +14 -14
  14. data/doc/appscript-manual/12_commandexamples.html +14 -14
  15. data/doc/appscript-manual/13_performanceissues.html +8 -5
  16. data/doc/appscript-manual/14_problemapps.html +4 -5
  17. data/doc/mactypes-manual/index.html +27 -9
  18. data/doc/osax-manual/index.html +1 -1
  19. data/rb-appscript-0.2.0.gem +0 -0
  20. data/rb-appscript.gemspec +1 -1
  21. data/sample/AB_list_people_with_emails.rb +2 -1
  22. data/sample/Create_daily_iCal_todos.rb +4 -3
  23. data/sample/Hello_world.rb +2 -1
  24. data/sample/List_iTunes_playlist_names.rb +2 -1
  25. data/sample/Make_Mail_message.rb +2 -1
  26. data/sample/Open_file_in_TextEdit.rb +2 -1
  27. data/sample/Organize_Mail_messages.rb +3 -2
  28. data/sample/Print_folder_tree.rb +2 -1
  29. data/sample/Select_all_HTML_files.rb +3 -2
  30. data/sample/Set_iChat_status.rb +4 -3
  31. data/sample/Simple_Finder_GUI_Scripting.rb +3 -2
  32. data/sample/Stagger_Finder_windows.rb +2 -1
  33. data/sample/TextEdit_demo.rb +6 -5
  34. data/sample/iTunes_top40_to_html.rb +3 -2
  35. data/src/lib/_aem/mactypes.rb +24 -2
  36. data/src/lib/_appscript/referencerenderer.rb +7 -7
  37. data/src/lib/appscript.rb +32 -12
  38. data/src/lib/osax.rb +21 -19
  39. data/src/rbae.c +0 -12
  40. data/test/test_appscriptreference.rb +30 -30
  41. metadata +3 -2
data/CHANGES CHANGED
@@ -1,3 +1,20 @@
1
+ 2006-11-29 -- 0.2.1
2
+
3
+ - renamed AS module to Appscript. An 'AS' alias is temporarily provided for backwards compatibility but this will be removed in a future release. Users should update their scripts accordingly.
4
+
5
+ - _appscript/referencerenderer.rb no longer prefixes 'AS.' to reference representation strings
6
+
7
+ - added #app, #con and #its instance methods to Appscript module to allow clients to include appscript methods and classes in other modules via 'include Appscript'; updated sample scripts and documentation to show this
8
+
9
+ - OSAX.scripting_additions now returns unique sorted names
10
+
11
+ - added MacTypes::Alias.url, MacTypes::Alias#url, MacTypes::File_URL.url, MacTypes::File_URL#url methods for working with file url strings
12
+
13
+ - OSAX::ScriptingAddition#to_s and #inspect now render scripting addition's name correctly
14
+
15
+ - removed unused AE.pid_to_psn method
16
+
17
+
1
18
  2006-11-20 -- 0.2.0
2
19
 
3
20
  - removed path expansion in FindApp#byName, MacFile::Alias#at, MacFile::FileURL#at
data/README CHANGED
@@ -27,7 +27,7 @@ Please note that the version of Ruby included with Mac OS X 10.4 is missing the
27
27
  ======================================================================
28
28
  NOTES
29
29
 
30
- - rb-appscript 0.2.0 contains a number of API changes from rb-appscript 0.1.x; see the CHANGES file and documentation for details
30
+ - rb-appscript 0.2.x contains a number of API changes from rb-appscript 0.1.x; see the CHANGES file and documentation for details
31
31
 
32
32
  ======================================================================
33
33
  AUTHOR
data/TODO CHANGED
@@ -2,8 +2,6 @@ TO DO
2
2
 
3
3
  - pack/unpack support for application types (note: packing would be a bit tricky, since app('foo') could also indicate a reference, in which case it should be packed as a null desc; unpacking might be a bit clumsy, and would (at least in theory) require a by_desc/by_aem_application method to be added to AS::Application to handle typeMachPort, other types could be converted to paths/creator codes/urls/etc. ok though)
4
4
 
5
- - remove rbAE_pidToPsn from rbae.c? (no longer used by connect.rb)
6
-
7
5
  - allow users to extract a generic ref from a real ref (to_generic) for comparison purposes. Or vice-versa?
8
6
 
9
7
  - implement built-in help system by bridging to py-appscript
@@ -12,8 +10,6 @@ TO DO
12
10
 
13
11
  - ae/aem/appscript-defined exception classes aren't quite idiomatic Ruby
14
12
 
15
- - finish commenting source code
16
-
17
13
  - would be nice if MacFile::FileNotFoundError always showed the failed path (this'd need a bit of Alias Manager glue added to the ae extension)
18
14
 
19
15
  - include an example project (or source for) that uses ruby2exe to build a standalone 'applet'
@@ -26,7 +26,7 @@
26
26
 
27
27
  <p>For example, to get the value of the first paragraph of the topmost document in TextEdit:</p>
28
28
 
29
- <pre><code>AS.app('TextEdit').documents[1].paragraphs[1].get</code></pre>
29
+ <pre><code>app('TextEdit').documents[1].paragraphs[1].get</code></pre>
30
30
 
31
31
  <p>This is equivalent to the AppleScript statement:</p>
32
32
 
@@ -53,8 +53,9 @@ end tell</code></pre>
53
53
  <pre><code>#!/usr/bin/env ruby
54
54
 
55
55
  require "appscript"
56
+ include Appscript
56
57
 
57
- AS.app('TextEdit').documents.end.make(
58
+ app('TextEdit').documents.end.make(
58
59
  :new => :document,
59
60
  :with_properties => {:text => "Hello World!\n"}
60
61
  )</code></pre>
@@ -52,11 +52,11 @@
52
52
 
53
53
  <p><img src="finder_to_textedit_event.gif" alt="Sending Apple event from Finder to TextEdit" /></p>
54
54
 
55
- <p>With suitable bindings, scripting languages can also create and send Apple events. For example, when the code <code>AS.app('iTunes').play</code> is executed in a Ruby interpreter, a <code>hook/Play</code> event is sent from the interpreter to iTunes, instructing it to start playing:</p>
55
+ <p>With suitable bindings, scripting languages can also create and send Apple events. For example, when the code <code>app('iTunes').play</code> is executed in a Ruby interpreter, a <code>hook/Play</code> event is sent from the interpreter to iTunes, instructing it to start playing:</p>
56
56
 
57
57
  <p><img src="ruby_to_itunes_event.gif" alt="Sending Apple event from Ruby to iTunes"/></p>
58
58
 
59
- <p>Applications may respond to an incoming Apple event by sending a reply event back to the client application. The reply event may contain either a return value, if there is one, or an error description if it was unable to handle the event as requested. For example, executing the command <code>AS.app('TextEdit').name.get</code> in a Ruby interpreter sends TextEdit a <code>code/getd</code> event containing an object specifier identifying the <code>name</code> property of its root <code>application</code> object. TextEdit processes this event, then sends a reply event containing the string '<tt>TextEdit</tt>' back to the Ruby interpreter, where it is displayed as the command's result. This exchange is usually performed synchronously, appearing to the user as a simple remote procedure call. Asynchronous messaging is also supported, though is not normally used in application scripting.</p>
59
+ <p>Applications may respond to an incoming Apple event by sending a reply event back to the client application. The reply event may contain either a return value, if there is one, or an error description if it was unable to handle the event as requested. For example, executing the command <code>app('TextEdit').name.get</code> in a Ruby interpreter sends TextEdit a <code>code/getd</code> event containing an object specifier identifying the <code>name</code> property of its root <code>application</code> object. TextEdit processes this event, then sends a reply event containing the string '<tt>TextEdit</tt>' back to the Ruby interpreter, where it is displayed as the command's result. This exchange is usually performed synchronously, appearing to the user as a simple remote procedure call. Asynchronous messaging is also supported, though is not normally used in application scripting.</p>
60
60
 
61
61
 
62
62
  <h2>What is a scriptable application?</h2>
@@ -203,8 +203,8 @@ app('TextEdit').documents[1].text.paragraphs</code></pre>
203
203
 
204
204
  <li>using appscript:
205
205
 
206
- <pre><code>AS.app('TextEdit').documents.text.paragraphs[
207
- AS.its.ne("\n")].characters[1].size.set(24)</code></pre>
206
+ <pre><code>app('TextEdit').documents.text.paragraphs[
207
+ its.ne("\n")].characters[1].size.set(24)</code></pre>
208
208
  </li>
209
209
  </ul>
210
210
 
@@ -35,15 +35,17 @@ irb(main):001:0&gt;</code></pre>
35
35
 
36
36
  <h3>Target TextEdit</h3>
37
37
 
38
- <p>The first step is to import the appscript module, <code>AS</code>, which exports the following functions and classes: <code>app</code>, <code>con</code>, <code>its</code>, <code>CommandError</code> and <code>ApplicationNotFoundError</code>.</p>
38
+ <p>The first step is to import the appscript module, <code>Appscript</code>, which provides the following functions and classes: <code>app</code>, <code>con</code>, <code>its</code>, <code>CommandError</code> and <code>ApplicationNotFoundError</code>.</p>
39
39
 
40
40
  <pre><code>irb&gt; require "appscript"
41
- =&gt; true</code></pre>
41
+ =&gt; true
42
+ irb&gt; include Appscript
43
+ =&gt; Object</code></pre>
42
44
 
43
45
  <p>Once appscript is imported, the first thing to do is to create new <code>app</code> object, identifying the application to be manipulated, and assign it to a variable, <code>te</code>, for easy reuse:</p>
44
46
 
45
- <pre><code>irb&gt; te = AS.app('TextEdit')
46
- =&gt; AS.app("/Applications/TextEdit.app")</code></pre>
47
+ <pre><code>irb&gt; te = app('TextEdit')
48
+ =&gt; app("/Applications/TextEdit.app")</code></pre>
47
49
 
48
50
  <p>The application may be identified by name, path, bundle ID, creator type, Unix process id, or, if running remotely, URL. If the application is identified by name, path, bundle ID or creator type and is not already running, it will be launched automatically for you.</p>
49
51
 
@@ -52,7 +54,7 @@ irb(main):001:0&gt;</code></pre>
52
54
  <p>First, create a new TextEdit document by making a new <code>document</code> object. This is done using the <code>make</code> command, passing it a single keyword parameter, <code>:new =&gt; :document</code>, indicating the type of object to create:</p>
53
55
 
54
56
  <pre><code>irb&gt; te.make(:new =&gt; :document)
55
- =&gt; AS.app("/Applications/TextEdit.app").documents[1]</code></pre>
57
+ =&gt; app("/Applications/TextEdit.app").documents[1]</code></pre>
56
58
 
57
59
  <p>Notice that keyword parameters are specified as an inline Hash with symbols as keys. The <a href="11_applicationcommands.html">Application Commands</a> chapter will discuss appscript's command syntax in more detail.</p>
58
60
 
@@ -61,7 +63,7 @@ irb(main):001:0&gt;</code></pre>
61
63
  <p>As you can see, the <code>make</code> command returns a reference identifying the newly-created object. This reference can be assigned to a variable for easy reuse. Use the <code>make</code> command to create another document, this time assigning its result to a variable, <code>doc</code>:</p>
62
64
 
63
65
  <pre><code>irb&gt; doc = te.make(:new =&gt; :document)
64
- =&gt; AS.app("/Applications/TextEdit.app").documents[1]</code></pre>
66
+ =&gt; app("/Applications/TextEdit.app").documents[1]</code></pre>
65
67
 
66
68
  <h3>Set the document's content</h3>
67
69
 
@@ -91,7 +93,7 @@ irb(main):001:0&gt;</code></pre>
91
93
 
92
94
  <pre><code>te.documents[1].text</code></pre>
93
95
 
94
- <p>the result is another reference, <code>AS.app("/Applications/TextEdit.app").documents[1].text</code>, not the value being referenced (<tt>'Hello World'</tt>). To get the value being referenced, you have to pass the reference as the direct argument to TextEdit's <code>get</code> command:</p>
96
+ <p>the result is another reference, <code>app("/Applications/TextEdit.app").documents[1].text</code>, not the value being referenced (<tt>'Hello World'</tt>). To get the value being referenced, you have to pass the reference as the direct argument to TextEdit's <code>get</code> command:</p>
95
97
 
96
98
  <pre><code>irb&gt; te.get(doc.text)
97
99
  =&gt; "Hello World!"</code></pre>
@@ -106,10 +108,10 @@ irb(main):001:0&gt;</code></pre>
106
108
  <pre><code>irb&gt; doc.text.get
107
109
  =&gt; "Hello World!"
108
110
  irb&gt; te.documents[1].get
109
- =&gt; AS.app("/Applications/TextEdit.app").documents[1]
111
+ =&gt; app("/Applications/TextEdit.app").documents[1]
110
112
  irb&gt; te.documents.get
111
- =&gt; [AS.app("/Applications/TextEdit.app").documents[1],
112
- AS.app("/Applications/TextEdit.app").documents[2]]
113
+ =&gt; [app("/Applications/TextEdit.app").documents[1],
114
+ app("/Applications/TextEdit.app").documents[2]]
113
115
  irb&gt; te.documents.text.get
114
116
  =&gt; ["Hello World", ""]</code></pre>
115
117
 
@@ -120,9 +122,9 @@ irb&gt; te.documents.text.get
120
122
  <p>The above exercise uses two commands to create a new TextEdit document containing the text '<tt>Hello World</tt>'. It is also possible to perform both operations using the <code>make</code> command alone by passing the value for the new document's <code>text</code> property via the <code>make</code> command's optional <code>with_properties</code> parameter:</p>
121
123
 
122
124
  <pre><code>irb&gt; te.make(:new =&gt; :document, :with_properties =&gt; {:text =&gt; 'Hello World'})
123
- =&gt; AS.app('/Applications/TextEdit.app').documents[1]</code></pre>
125
+ =&gt; app('/Applications/TextEdit.app').documents[1]</code></pre>
124
126
 
125
- <p>Incidentally, you might note that every time the <code>make</code> command is used, it returns a reference to document <em>1</em>. TextEdit identifies its <code>document</code> objects according to the stacking order of their windows, with document 1 being frontmost. When the window stacking order changes, whether as a result of a script command or GUI-based interaction, so does the order of their corresponding <code>document</code> objects. This means that a previously created reference such as <code>AS.app('/Applications/TextEdit.app').documents[1]</code> may now identify a different <code>document</code> object to before! Some applications prefer to return references that identify objects by name or unique ID rather than index to reduce or eliminate the potential for confusion, but it's an issue you should be aware of, particularly with long-running scripts where there is greater opportunity for unexpected third-party interactions to throw a spanner in the works.</p>
127
+ <p>Incidentally, you might note that every time the <code>make</code> command is used, it returns a reference to document <em>1</em>. TextEdit identifies its <code>document</code> objects according to the stacking order of their windows, with document 1 being frontmost. When the window stacking order changes, whether as a result of a script command or GUI-based interaction, so does the order of their corresponding <code>document</code> objects. This means that a previously created reference such as <code>app('/Applications/TextEdit.app').documents[1]</code> may now identify a different <code>document</code> object to before! Some applications prefer to return references that identify objects by name or unique ID rather than index to reduce or eliminate the potential for confusion, but it's an issue you should be aware of, particularly with long-running scripts where there is greater opportunity for unexpected third-party interactions to throw a spanner in the works.</p>
126
128
 
127
129
 
128
130
  <h3>More on manipulating <code>text</code></h3>
@@ -52,7 +52,7 @@
52
52
 
53
53
  <p>Examples</p>
54
54
 
55
- <pre><code>te = AS.app('TextEdit')
55
+ <pre><code>te = app('TextEdit')
56
56
 
57
57
  p te.commands
58
58
  # ["activate", "close", "count", "delete", "duplicate", "exists", ...]
@@ -67,8 +67,8 @@ AEM::AEEnum.new('xyz ')</code></pre>
67
67
  <tr><td><code>typeFileURL</code></td><td><code>:file_url</code></td><td><code>MacTypes::FileURL</code></td></tr>
68
68
  <tr><td><code>typeFSRef</code></td><td><code>:file_ref</code></td><td><code>MacTypes::FileURL</code></td></tr>
69
69
  <tr><td><code>typeFSS</code> *</td><td><code>:file_specification</code></td><td><code>MacTypes::FileURL</code></td></tr>
70
- <tr><td><code>typeObjectSpecifier</code></td><td><code>:reference</code></td><td><code>AS::Reference</code></td></tr>
71
- <tr><td><code>typeInsertionLoc</code></td><td><code>:location_reference</code></td><td><code>AS::Reference</code></td></tr>
70
+ <tr><td><code>typeObjectSpecifier</code></td><td><code>:reference</code></td><td><code>Appscript::Reference</code></td></tr>
71
+ <tr><td><code>typeInsertionLoc</code></td><td><code>:location_reference</code></td><td><code>Appscript::Reference</code></td></tr>
72
72
  <tr><td><code>typeType</code></td><td><code>:type_class</code></td><td><code>Symbol</code></td></tr>
73
73
  <tr><td><code>typeEnumerated</code></td><td><code>:enumerator</code></td><td><code>Symbol</code></td></tr>
74
74
  <tr><td><small>unit types; e.g. </small> <code>typeFeet</code></td><td><small>unit names; e.g.</small> <code>:feet</code></td><td><code>MacTypes::Units</code></td></tr>
@@ -114,7 +114,7 @@ $KCODE = "UTF8"</code></pre>
114
114
 
115
115
  <p>When asking an application to coerce a return value into a file type you must specify the exact type (<code>:alias</code>, <code>:file_url</code>, <code>:file_ref</code>, or <code>:file_specification</code>) in the <code>get</code> command. e.g. To get a <code>MacTypes::FileURL</code> object for the current user's home folder, you would usually use:</p>
116
116
 
117
- <pre><code>AS.app('Finder').home.get(:result_type=&gt;:file_url)</code></pre>
117
+ <pre><code>app('Finder').home.get(:result_type=&gt;:file_url)</code></pre>
118
118
 
119
119
  <p>Also be aware that some applications may not support coercions to all AE file types; you'll need to experiment to find out which coercions are supported.</p>
120
120
 
@@ -25,21 +25,21 @@
25
25
 
26
26
  <p>Before you can communicate with a scriptable application you must call one of the following methods to create an application object:</p>
27
27
 
28
- <pre><code>AS.app.by_name(name) # name or POSIX path of local application
28
+ <pre><code>app.by_name(name) # name or POSIX path of local application
29
29
 
30
- AS.app.by_id(id) # bundle ID for a local application
30
+ app.by_id(id) # bundle ID for a local application
31
31
 
32
- AS.app.by_creator(creator) # 4-character creator type for a local application
32
+ app.by_creator(creator) # 4-character creator type for a local application
33
33
 
34
- AS.app.by_pid(pid) # Unix process id for a local process
34
+ app.by_pid(pid) # Unix process id for a local process
35
35
 
36
- AS.app.by_url(url) # eppc URL for a remote process
36
+ app.by_url(url) # eppc URL for a remote process
37
37
 
38
- AS.app.current # the host process</code></pre>
38
+ app.current # the host process</code></pre>
39
39
 
40
- <p>For convenience, the most commonly used form, <code>AS.app.by_name(name)</code>, can be shortened to:</p>
40
+ <p>For convenience, the most commonly used form, <code>app.by_name(name)</code>, can be shortened to:</p>
41
41
 
42
- <pre><code>AS.app(name)</code></pre>
42
+ <pre><code>app(name)</code></pre>
43
43
 
44
44
 
45
45
  <p>To target an application you must supply one of the following arguments:</p>
@@ -65,20 +65,21 @@ AS.app.current # the host process</code></pre>
65
65
  <p>Examples:</p>
66
66
 
67
67
  <pre><code>require "appscript"
68
+ include Appscript
68
69
 
69
- ical = AS.app('iCal')
70
+ ical = app('iCal')
70
71
 
71
- textedit = AS.app('TextEdit.app')
72
+ textedit = app('TextEdit.app')
72
73
 
73
- safari = AS.app('/Applications/Safari')
74
+ safari = app('/Applications/Safari')
74
75
 
75
- addressbook = AS.app.by_id('com.apple.addressbook')
76
+ addressbook = app.by_id('com.apple.addressbook')
76
77
 
77
- quicktimeplayer = AS.app.by_creator('TVOD')
78
+ quicktimeplayer = app.by_creator('TVOD')
78
79
 
79
- finder = AS.app.by_url('eppc://192.168.10.1/Finder')
80
+ finder = app.by_url('eppc://192.168.10.1/Finder')
80
81
 
81
- itunes = AS.app.by_url('eppc://Jan%20Smith@G4.local/iTunes')</code></pre>
82
+ itunes = app.by_url('eppc://Jan%20Smith@G4.local/iTunes')</code></pre>
82
83
 
83
84
 
84
85
  <h2>Basic commands</h2>
@@ -146,7 +147,7 @@ set(reference, :to =&gt; value) -- Set an object's data.
146
147
 
147
148
  <p>When appscript launches a non-running application, it normally sends it a <code>run</code> command as part of the launching process. If you wish to avoid this, you should start the application by sending it a <code>launch</code> command before doing anything else. For example:</p>
148
149
 
149
- <pre><code>te = AS.app('TextEdit')
150
+ <pre><code>te = app('TextEdit')
150
151
  te.launch
151
152
  # other TextEdit-related code goes here...</code></pre>
152
153
 
@@ -27,45 +27,45 @@
27
27
 
28
28
  <p>A real reference begins with an <code>app</code> call, followed by a <code>by_name</code>, <code>by_id</code>, <code>by_creator</code>, <code>by_pid</code>, <code>by_url</code> call that identifies the application whose object(s) it refers to, e.g.:</p>
29
29
 
30
- <pre><code>AS.app.by_name('TextEdit').documents.end
31
- AS.app.by_url('eppc://my-mac.local/Finder').home.folders.name</code></pre>
30
+ <pre><code>app.by_name('TextEdit').documents.end
31
+ app.by_url('eppc://my-mac.local/Finder').home.folders.name</code></pre>
32
32
 
33
- <p>(Remember than <code>AS.app.by_name('TextEdit')</code> can be shortened to <code>AS.app('TextEdit')</code> for convenience.</p>
33
+ <p>(Remember than <code>app.by_name('TextEdit')</code> can be shortened to <code>app('TextEdit')</code> for convenience.</p>
34
34
 
35
35
  <p>A generic reference begins with <code>app</code>, <code>con</code> or <code>its</code> and does not identify the application to which it relates, e.g.:</p>
36
36
 
37
- <pre><code>AS.app.documents.end
38
- AS.con.word[3]
39
- AS.its.name.starts_with('d')</code></pre>
37
+ <pre><code>app.documents.end
38
+ con.word[3]
39
+ its.name.starts_with('d')</code></pre>
40
40
 
41
41
  <p>Generic references are only evaluated when used used within real references, either as selectors:</p>
42
42
 
43
- <pre><code>AS.app('Finder').home.folders[<em>AS.its.name.starts_with('d')</em>].get
43
+ <pre><code>app('Finder').home.folders[<em>its.name.starts_with('d')</em>].get
44
44
 
45
- AS.app('Tex-Edit Plus').windows[1].text[<em>AS.con.words[2]</em>, <em>AS.con.words[-2]</em>].get</code></pre>
45
+ app('Tex-Edit Plus').windows[1].text[<em>con.words[2]</em>, <em>con.words[-2]</em>].get</code></pre>
46
46
 
47
47
  <p>or as command parameters:</p>
48
48
 
49
- <pre><code>AS.app('TextEdit').make(
49
+ <pre><code>app('TextEdit').make(
50
50
  :new =&gt; :word,
51
- :at =&gt; <em>AS.app.documents[1].words.end</em>,
51
+ :at =&gt; <em>app.documents[1].words.end</em>,
52
52
  :with_data =&gt; 'Hello')
53
53
 
54
- AS.app('Finder').desktop.duplicate(
55
- :to =&gt; <em>AS.app.home.folders['Desktop Copy']</em>)</code></pre>
54
+ app('Finder').desktop.duplicate(
55
+ :to =&gt; <em>app.home.folders['Desktop Copy']</em>)</code></pre>
56
56
 
57
57
 
58
58
  <h2>Comparing and hashing references</h2>
59
59
 
60
60
  <p>Application references can be compared for equality and are hashable (so can be used as dictionary keys). For two real references to be considered equal, both must have the same application path or url and reference structure. Examples:</p>
61
61
 
62
- <pre><code>puts AS.app('TextEdit').documents[1] == \
63
- AS.app.by_id('com.apple.textedit').documents[1].get
62
+ <pre><code>puts app('TextEdit').documents[1] == \
63
+ app.by_id('com.apple.textedit').documents[1].get
64
64
  # Result: true; both references evaluate to the same
65
65
  # application path and reference
66
66
 
67
- puts AS.app('Finder').home == AS.app('Finder').home.get
68
- # Result: false; AS.app('Finder').home.get returns a
67
+ puts app('Finder').home == app('Finder').home.get
68
+ # Result: false; app('Finder').home.get returns a
69
69
  # different reference to the same location</code></pre>
70
70
 
71
71
  <p>For two generic references to be equal, both must have the same reference structure. Note that comparing generic references to real references will always return a false result.</p>
@@ -117,11 +117,11 @@ paragraphs[-1].previous(:character)</code></pre>
117
117
 
118
118
  <p>Range references select all elements between and including two references indicating the start and end of the range. The start and end references are normally declared relative to the container of the elements being selected. Appscript defines an object, <code>con</code> (short for 'container'), to indicate this container; for example, to indicate the third paragraph of the currrent container object:</p>
119
119
 
120
- <pre><code>AS.con.paragraphs[3]</code></pre>
120
+ <pre><code>con.paragraphs[3]</code></pre>
121
121
 
122
122
  <p>For convenience, the range reference also allows start and end references to be written in shorthand form where their element class is the same as the elements being selected; thus:</p>
123
123
 
124
- <pre><code>ref.paragraphs[AS.con.paragraphs[3], AS.con.paragraphs[-1]]</code></pre>
124
+ <pre><code>ref.paragraphs[con.paragraphs[3], con.paragraphs[-1]]</code></pre>
125
125
 
126
126
  <p>can also be written as:</p>
127
127
 
@@ -129,7 +129,7 @@ paragraphs[-1].previous(:character)</code></pre>
129
129
 
130
130
  <p>Some applications can handle more complex range references. For example, the following will work in Tex-Edit Plus:</p>
131
131
 
132
- <pre><code>ref.words[AS.con.characters[5], AS.con.paragraphs[-2]]</code></pre>
132
+ <pre><code>ref.words[con.characters[5], con.paragraphs[-2]]</code></pre>
133
133
 
134
134
  <p>Syntax:</p>
135
135
  <pre><code>elements[start, end]
@@ -139,7 +139,7 @@ paragraphs[-1].previous(:character)</code></pre>
139
139
  <p>Examples:</p>
140
140
  <pre><code>folders['Documents', 'Movies']
141
141
  documents[1, 3]
142
- text[AS.con.characters[5], AS.con.words[-2]]</code></pre>
142
+ text[con.characters[5], con.words[-2]]</code></pre>
143
143
 
144
144
  <p class="hilitebox">Note: ranges are specified as [start-position, <em>end-position</em>] (AEM-style ranges), not [start-position, <em>length</em>] (Ruby-style ranges).</p>
145
145
 
@@ -154,9 +154,9 @@ text[AS.con.characters[5], AS.con.words[-2]]</code></pre>
154
154
  <ul>
155
155
  <li><p>A reference to each element being tested, represented by appscript's <code>its</code> object. This object supports all valid reference forms, allowing you to construct references to its properties and elements. For example:</p>
156
156
 
157
- <pre><code>AS.its
158
- AS.its.size
159
- AS.its.words.first</code></pre></li>
157
+ <pre><code>its
158
+ its.size
159
+ its.words.first</code></pre></li>
160
160
 
161
161
  <li><p>One or more conditional tests, implemented as methods on the reference being tested. Each method takes a test reference or a value as their sole argument.</p>
162
162
 
@@ -178,12 +178,12 @@ reference.is_not_in(value)
178
178
  value : reference or value</code></pre>
179
179
 
180
180
  <p>Examples:</p>
181
- <pre><code>AS.its.eq('')
182
- AS.its.size.gt(1024)
183
- AS.its.words.first.starts_with('A')
184
- AS.its.characters.first.eq(AS.its.characters.last)</code></pre>
181
+ <pre><code>its.eq('')
182
+ its.size.gt(1024)
183
+ its.words.first.starts_with('A')
184
+ its.characters.first.eq(its.characters.last)</code></pre>
185
185
 
186
- <p>Note that Boolean comparison tests can be written as either <code>reference.eq(true)</code> or just <code>reference</code>, e.g. <code>folderRef.files[AS.its.locked]</code></p></li>
186
+ <p>Note that Boolean comparison tests can be written as either <code>reference.eq(true)</code> or just <code>reference</code>, e.g. <code>folderRef.files[its.locked]</code></p></li>
187
187
 
188
188
  <li><p>Zero or more logical tests, implemented as properties/methods on conditional tests. The <code>and</code> and <code>or</code> methods take one or more conditional or logic tests as arguments.</p>
189
189
 
@@ -193,9 +193,9 @@ test.or(test, ...)
193
193
  test.not</code></pre>
194
194
 
195
195
  <p>Examples:</p>
196
- <pre><code>AS.its.eq('').not
197
- AS.its.size.gt(1024).and(its.size.lt(10240))
198
- AS.its.words[1].starts_with('A').or(
196
+ <pre><code>its.eq('').not
197
+ its.size.gt(1024).and(its.size.lt(10240))
198
+ its.words[1].starts_with('A').or(
199
199
  its.words[2].contains('ce'),
200
200
  its.words[1].eq('Foo'))</code></pre></li>
201
201
  </ul>
@@ -23,108 +23,109 @@
23
23
  <h2>Application objects</h2>
24
24
 
25
25
  <pre><code>require "appscript"
26
+ include Appscript
26
27
 
27
28
  # application &quot;Finder&quot;
28
- AS.app('Finder')
29
+ app('Finder')
29
30
 
30
31
  # application &quot;Macintosh HD:Applications:TextEdit.app:&quot;
31
- AS.app('/Applications/TextEdit.app')</code></pre>
32
+ app('/Applications/TextEdit.app')</code></pre>
32
33
 
33
34
 
34
35
  <h2>Property References</h2>
35
36
 
36
37
  <pre><code># a reference to startup disk of application &quot;Finder&quot;
37
- AS.app('Finder').startup_disk
38
+ app('Finder').startup_disk
38
39
 
39
40
  # a reference to name of folder 1 of home of application &quot;Finder&quot;
40
- AS.app('Finder').home.folders[1].name
41
+ app('Finder').home.folders[1].name
41
42
 
42
43
  # a reference to name of every item of home of application &quot;Finder&quot;
43
- AS.app('Finder').home.items.name
44
+ app('Finder').home.items.name
44
45
 
45
46
  # a reference to text of every document of application &quot;TextEdit&quot;
46
- AS.app('TextEdit').documents.text
47
+ app('TextEdit').documents.text
47
48
 
48
49
  # a reference to color of character 1 of every paragraph of text &not;
49
50
  # of document 1 of application &quot;TextEdit&quot;
50
- AS.app('TextEdit').documents[1].text.paragraphs.characters[1].color</code></pre>
51
+ app('TextEdit').documents[1].text.paragraphs.characters[1].color</code></pre>
51
52
 
52
53
 
53
54
  <h2>All Elements References</h2>
54
55
 
55
56
  <pre><code># a reference to disks of application &quot;Finder&quot;
56
- AS.app('Finder').disks
57
+ app('Finder').disks
57
58
 
58
59
  # a reference to every word of every paragraph of text of every document &not;
59
60
  # of application &quot;TextEdit&quot;
60
- AS.app('TextEdit').documents.text.paragraphs.words</code></pre>
61
+ app('TextEdit').documents.text.paragraphs.words</code></pre>
61
62
 
62
63
 
63
64
  <h2>Single Element References</h2>
64
65
 
65
66
  <pre><code># a reference to disk 1 of application &quot;Finder&quot;
66
- AS.app('Finder').disks[1]
67
+ app('Finder').disks[1]
67
68
 
68
69
  # a reference to file &quot;ReadMe.txt&quot; of folder &quot;Documents&quot; of home of application &quot;Finder&quot;
69
- AS.app('Finder').home.folders['Documents'].files['ReadMe.txt']
70
+ app('Finder').home.folders['Documents'].files['ReadMe.txt']
70
71
 
71
72
  # a reference to paragraph -1 of text of document 1 of application &quot;TextEdit&quot;
72
- AS.app('TextEdit').documents[1].text.paragraphs[-1]
73
+ app('TextEdit').documents[1].text.paragraphs[-1]
73
74
 
74
75
  # a reference to middle paragraph of text of last document of application &quot;TextEdit&quot;
75
- AS.app('TextEdit').documents.last.text.paragraphs.middle
76
+ app('TextEdit').documents.last.text.paragraphs.middle
76
77
 
77
78
  # a reference to any file of home of application &quot;Finder&quot;
78
- AS.app('Finder').home.files.any</code></pre>
79
+ app('Finder').home.files.any</code></pre>
79
80
 
80
81
 
81
82
  <h2>Relative References</h2>
82
83
 
83
84
  <pre><code># a reference to paragraph before paragraph 6 of text of document 1 of application &quot;TextEdit&quot;
84
- AS.app('TextEdit').documents[1].text.paragraphs[6].previous(:paragraph)
85
+ app('TextEdit').documents[1].text.paragraphs[6].previous(:paragraph)
85
86
 
86
87
  # a reference to paragraph after character 30 of document 1 of application &quot;Tex-Edit Plus&quot;
87
- AS.app('Tex-Edit Plus').documents[1].characters[30].next(:paragraph)</code></pre>
88
+ app('Tex-Edit Plus').documents[1].characters[30].next(:paragraph)</code></pre>
88
89
 
89
90
 
90
91
  <h2>Element Range References</h2>
91
92
 
92
93
  <pre><code># a reference to words 1 thru 4 of text of document 1 of application &quot;TextEdit&quot;
93
- AS.app('TextEdit').documents[1].text.words[1, 4]
94
+ app('TextEdit').documents[1].text.words[1, 4]
94
95
 
95
96
  # a reference to paragraphs 2 thru -1 of text of document 1 of application &quot;TextEdit&quot;
96
- AS.app('TextEdit').documents[1].text.paragraphs[2, -1]
97
+ app('TextEdit').documents[1].text.paragraphs[2, -1]
97
98
 
98
99
  # a reference to folders &quot;Documents&quot; thru &quot;Music&quot; of home of application &quot;Finder&quot;
99
- AS.app('Finder').home.folders['Documents', 'Music']
100
+ app('Finder').home.folders['Documents', 'Music']
100
101
 
101
102
  # a reference to text (word 3) thru (paragraph 7) of document 1 of application &quot;Tex-Edit Plus&quot;
102
- AS.app('Tex-Edit Plus').documents[1].text[AS.con.words[3], AS.con.paragraphs[7]]</code></pre>
103
+ app('Tex-Edit Plus').documents[1].text[con.words[3], con.paragraphs[7]]</code></pre>
103
104
 
104
105
 
105
106
  <h2>Filter References</h2>
106
107
 
107
108
  <pre><code># a reference to every document of application &quot;TextEdit&quot; whose text is &quot;\n&quot;
108
- AS.app('TextEdit').documents[AS.its.text.eq("\n")]
109
+ app('TextEdit').documents[its.text.eq("\n")]
109
110
 
110
111
  # a reference to every paragraph of document 1 of application &quot;Tex-Edit Plus&quot; &not;
111
112
  # whose first character is last character
112
- AS.app('Tex-Edit Plus').documents[1].paragraphs[
113
- AS.its.characters.first.eq(AS.its.characters.last)]
113
+ app('Tex-Edit Plus').documents[1].paragraphs[
114
+ its.characters.first.eq(its.characters.last)]
114
115
 
115
116
  # a reference to every file of folder &quot;Documents&quot; of home of application &quot;Finder&quot; &not;
116
117
  # whose name extension is &quot;txt&quot; and size < 10240
117
- AS.app('Finder').home.folders['Documents'].files[
118
- AS.its.name_extension.eq('txt').AND(AS.its.size.lt(10240))]</code></pre>
118
+ app('Finder').home.folders['Documents'].files[
119
+ its.name_extension.eq('txt').AND(its.size.lt(10240))]</code></pre>
119
120
 
120
121
 
121
122
  <h2>Insertion Location References</h2>
122
123
 
123
124
  <pre><code># a reference to end of documents of application &quot;TextEdit&quot;
124
- AS.app('TextEdit').documents.end
125
+ app('TextEdit').documents.end
125
126
 
126
127
  # a reference to before paragraph 1 of text of document 1 of application &quot;TextEdit&quot;
127
- AS.app('TextEdit').documents[1].text.paragraphs[1].before</code></pre>
128
+ app('TextEdit').documents[1].text.paragraphs[1].before</code></pre>
128
129
 
129
130
 
130
131