rb-appscript 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES +243 -0
- data/LICENSE +1 -0
- data/README +42 -0
- data/TODO +31 -0
- data/doc/aem-manual/01_introduction.html +48 -0
- data/doc/aem-manual/02_apioverview.html +89 -0
- data/doc/aem-manual/03_packingandunpackingdata.html +98 -0
- data/doc/aem-manual/04_references.html +401 -0
- data/doc/aem-manual/05_targettingapplications.html +133 -0
- data/doc/aem-manual/06_buildingandsendingevents.html +175 -0
- data/doc/aem-manual/07_findapp.html +54 -0
- data/doc/aem-manual/08_examples.html +85 -0
- data/doc/aem-manual/09_notes.html +41 -0
- data/doc/aem-manual/aemreferenceinheritance.gif +0 -0
- data/doc/aem-manual/full.css +21 -0
- data/doc/aem-manual/index.html +43 -0
- data/doc/appscript-manual/01_introduction.html +82 -0
- data/doc/appscript-manual/02_aboutappscripting.html +244 -0
- data/doc/appscript-manual/03_quicktutorial.html +154 -0
- data/doc/appscript-manual/04_gettinghelp.html +101 -0
- data/doc/appscript-manual/05_keywordconversion.html +91 -0
- data/doc/appscript-manual/06_classesandenums.html +174 -0
- data/doc/appscript-manual/07_applicationobjects.html +181 -0
- data/doc/appscript-manual/08_realvsgenericreferences.html +86 -0
- data/doc/appscript-manual/09_referenceforms.html +232 -0
- data/doc/appscript-manual/10_referenceexamples.html +142 -0
- data/doc/appscript-manual/11_applicationcommands.html +204 -0
- data/doc/appscript-manual/12_commandexamples.html +129 -0
- data/doc/appscript-manual/13_performanceissues.html +115 -0
- data/doc/appscript-manual/14_problemapps.html +193 -0
- data/doc/appscript-manual/15_notes.html +84 -0
- data/doc/appscript-manual/application_architecture.gif +0 -0
- data/doc/appscript-manual/application_architecture2.gif +0 -0
- data/doc/appscript-manual/finder_to_textedit_event.gif +0 -0
- data/doc/appscript-manual/full.css +21 -0
- data/doc/appscript-manual/index.html +49 -0
- data/doc/appscript-manual/relationships_example.gif +0 -0
- data/doc/appscript-manual/ruby_to_itunes_event.gif +0 -0
- data/doc/index.html +30 -0
- data/doc/mactypes-manual/index.html +216 -0
- data/doc/osax-manual/index.html +169 -0
- data/extconf.rb +54 -0
- data/misc/adobeunittypes.rb +14 -0
- data/misc/dump.rb +72 -0
- data/rb-appscript.gemspec +20 -0
- data/sample/AB_list_people_with_emails.rb +8 -0
- data/sample/Create_daily_iCal_todos.rb +72 -0
- data/sample/Hello_world.rb +9 -0
- data/sample/List_iTunes_playlist_names.rb +7 -0
- data/sample/Make_Mail_message.rb +29 -0
- data/sample/Open_file_in_TextEdit.rb +9 -0
- data/sample/Organize_Mail_messages.rb +57 -0
- data/sample/Print_folder_tree.rb +12 -0
- data/sample/Select_all_HTML_files.rb +8 -0
- data/sample/Set_iChat_status.rb +20 -0
- data/sample/Simple_Finder_GUI_Scripting.rb +14 -0
- data/sample/Stagger_Finder_windows.rb +21 -0
- data/sample/TextEdit_demo.rb +126 -0
- data/sample/iTunes_top40_to_html.rb +64 -0
- data/src/lib/_aem/aemreference.rb +1006 -0
- data/src/lib/_aem/codecs.rb +617 -0
- data/src/lib/_aem/connect.rb +100 -0
- data/src/lib/_aem/findapp.rb +83 -0
- data/src/lib/_aem/mactypes.rb +228 -0
- data/src/lib/_aem/send.rb +257 -0
- data/src/lib/_aem/typewrappers.rb +57 -0
- data/src/lib/_appscript/defaultterminology.rb +245 -0
- data/src/lib/_appscript/referencerenderer.rb +132 -0
- data/src/lib/_appscript/reservedkeywords.rb +107 -0
- data/src/lib/_appscript/terminology.rb +314 -0
- data/src/lib/aem.rb +216 -0
- data/src/lib/appscript.rb +830 -0
- data/src/lib/kae.rb +1484 -0
- data/src/lib/osax.rb +171 -0
- data/src/rbae.c +766 -0
- data/test/README +1 -0
- data/test/test_aemreference.rb +112 -0
- data/test/test_appscriptreference.rb +102 -0
- data/test/test_codecs.rb +159 -0
- data/test/test_findapp.rb +24 -0
- data/test/test_mactypes.rb +67 -0
- data/test/testall.sh +9 -0
- metadata +143 -0
@@ -0,0 +1,216 @@
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
2
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
3
|
+
<head>
|
4
|
+
|
5
|
+
<title>mactypes</title>
|
6
|
+
|
7
|
+
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
8
|
+
<style type="text/css" media="all"><!--@import url(../appscript-manual/full.css);--></style>
|
9
|
+
|
10
|
+
</head>
|
11
|
+
<body>
|
12
|
+
|
13
|
+
<h1>mactypes</h1>
|
14
|
+
|
15
|
+
<!-- top navigation -->
|
16
|
+
<div class="navbar">
|
17
|
+
<a href="index.html">Up</a>
|
18
|
+
|
19
|
+
</div>
|
20
|
+
|
21
|
+
<!-- content -->
|
22
|
+
<div id="content">
|
23
|
+
<h2>What is mactypes?</h2>
|
24
|
+
|
25
|
+
<p>The mactypes module provides user-friendly wrappers for OS X Alias and File objects, commonly used by scriptable applications to identify filesystem objects and locations, and for unit type values used by some applications to represent lengths, etc. It is automatically imported when requiring appscript, aem or osax.</p>
|
26
|
+
|
27
|
+
<p class="hilitebox">Note that most scriptable applications do not use or understand POSIX paths, and while the Apple Event Manager does provide some built-in coercions for converting between path strings and alias/file objects, these work with HFS paths only. Therefore, when specifying files and folders to scriptable applications, use <code>MacTypes::Alias</code> and <code>MacTypes::FileURL</code> objects - not path strings - unless otherwise indicated.</p>
|
28
|
+
|
29
|
+
|
30
|
+
<h2><code>MacTypes::Alias</code></h2>
|
31
|
+
|
32
|
+
<p>The <code>Alias</code> class represents a persistent reference to a filesystem object. Aliases keep track of filesystem objects even if they're renamed or moved to another location on the same disk.</p>
|
33
|
+
|
34
|
+
|
35
|
+
<h3>Methods</h3>
|
36
|
+
|
37
|
+
<pre><code>Alias -- a persistent reference to a filesystem object
|
38
|
+
Constructors:
|
39
|
+
|
40
|
+
Alias.path(path) -- make Alias object from POSIX path
|
41
|
+
|
42
|
+
Alias.desc(desc) -- make Alias object from an AE::AEDesc
|
43
|
+
of TypeAlias
|
44
|
+
|
45
|
+
Methods:
|
46
|
+
|
47
|
+
path -- returns POSIX path string to the object's current location
|
48
|
+
|
49
|
+
desc -- returns AE::AEDesc of TypeAlias
|
50
|
+
|
51
|
+
to_s -- synonym for #path
|
52
|
+
|
53
|
+
inspect -- returns string representation of Alias object
|
54
|
+
|
55
|
+
to_alias -- returns self
|
56
|
+
|
57
|
+
to_file_url -- returns a MacTypes::FileURL object</code></pre>
|
58
|
+
|
59
|
+
|
60
|
+
<h3>Examples</h3>
|
61
|
+
|
62
|
+
<pre><code>require "appscript"
|
63
|
+
|
64
|
+
f = MacTypes::Alias.path('/Users/foo/some file')
|
65
|
+
|
66
|
+
puts f.to_s
|
67
|
+
# /Users/foo/some file
|
68
|
+
|
69
|
+
puts f.inspect
|
70
|
+
# MacTypes::Alias.path("/Users/foo/some file")
|
71
|
+
|
72
|
+
AS.app('TextEdit').open(f)
|
73
|
+
# opens document in TextEdit</code></pre>
|
74
|
+
|
75
|
+
|
76
|
+
<h3>Notes</h3>
|
77
|
+
|
78
|
+
<p>Note that comparing an <code>Alias</code> object against an <code>FileURL</code> object always returns false, even if both point to the same location.</p>
|
79
|
+
|
80
|
+
|
81
|
+
|
82
|
+
<h2><code>MacTypes::FileURL</code></h2>
|
83
|
+
|
84
|
+
<p>The <code>FileURL</code> class represents a fixed filesystem location. This may be deterministic (i.e. existing locations only) or non-deterministic depending on how the object is created.</p>
|
85
|
+
|
86
|
+
<h3>Methods</h3>
|
87
|
+
|
88
|
+
<pre><code>FileURL -- identifies a fixed filesystem location
|
89
|
+
Constructors:
|
90
|
+
|
91
|
+
FileURL.path(path) -- make FileURL object from POSIX path
|
92
|
+
|
93
|
+
FileURL.desc(desc) -- make FileURL object from an AE::AEDesc
|
94
|
+
of TypeFSS, TypeFSRef or TypeFileURL
|
95
|
+
|
96
|
+
Methods:
|
97
|
+
|
98
|
+
==
|
99
|
+
|
100
|
+
hash
|
101
|
+
|
102
|
+
path -- returns POSIX path string
|
103
|
+
|
104
|
+
desc -- returns AE::AEDesc of TypeFSRef, TypeFSS or TypeFileURL
|
105
|
+
|
106
|
+
to_s -- synonym for #path
|
107
|
+
|
108
|
+
inspect -- returns string representation of FileURL object
|
109
|
+
|
110
|
+
to_alias -- returns a MacTypes::Alias object
|
111
|
+
|
112
|
+
to_file_url -- returns a new MacTypes::FileURL object</code></pre>
|
113
|
+
|
114
|
+
|
115
|
+
<h3>Examples</h3>
|
116
|
+
|
117
|
+
<pre><code>require "appscript"
|
118
|
+
|
119
|
+
f = MacTypes::FileURL.path('/Users/foo/new file')
|
120
|
+
|
121
|
+
puts f.to_s
|
122
|
+
# /Users/foo/new file
|
123
|
+
|
124
|
+
puts f.inspect
|
125
|
+
# MacTypes::FileURL.path("/Users/foo/new file")
|
126
|
+
|
127
|
+
AS.app('TextEdit').documents[1].save(:in => f)
|
128
|
+
# saves front TextEdit document at the given location</code></pre>
|
129
|
+
|
130
|
+
|
131
|
+
<h3>Notes</h3>
|
132
|
+
|
133
|
+
<p>Unlike the <code>Alias</code> class which wraps <code>TypeAlias</code> values only, the <code>FileURL</code> class provides a uniform wrapper for several file-related types that may be returned by applications: <code>TypeFSS</code>, <code>TypeFSRef</code> and <code>TypeFileURL</code>. When passing <code>FileURL</code> values to applications, you should not normally need to worry about which value type a <code>FileURL</code> object contains as well-designed applications will ask the Apple Event Manager to coerce the given value to the desired type as necessary.</p>
|
134
|
+
|
135
|
+
<p>When dealing with less well-behaved applications, however, you may need to pass an AEDesc of a specific type. In this case you should use the <code>desc</code> method to obtain an <code>AE::AEDesc</code> object, then call its <code>coerce</code> method to obtain an AEDesc of the desired type. For example, if an older Carbon application refuses to accept a FileURL identifying a non-existing file location, you may need to provide a FSSpec insteaf:</p>
|
136
|
+
|
137
|
+
<pre><code>require "appscript"
|
138
|
+
|
139
|
+
file_url = MacTypes::FileURL.path('/Users/foo/new file')
|
140
|
+
|
141
|
+
fs_spec = file_url.desc.coerce(KAE::TypeFSS)
|
142
|
+
|
143
|
+
AS.app('older app').documents[1].save(:in => fs_spec)</code></pre>
|
144
|
+
|
145
|
+
<p>When used in an application command, a <code>FileURL</code> object returned by appscript will always pack into the same <code>TypeFSRef</code>, <code>TypeFileURL</code> or <code>TypeFSS</code> AEDesc it was created from. A <code>FileURL</code> object returned by <code>FileURL.path</code>, <code>Alias#to_file_url</code> or <code>FileURL#to_file_url</code> will always pack into an AEDesc of <code>TypeFileURL</code>.</p>
|
146
|
+
|
147
|
+
<p>Note that comparing <code>FileURL</code> objects only tests for exact data equality; two objects that identify the same filesystem location by different means (e.g.comparing a <code>FileURL</code> object that was created from an existing AEDesc of <code>TypeFSRef</code> against one created from scratch), using paths of different case, etc. will test as false.</p>
|
148
|
+
|
149
|
+
<p>Note that AEDescs of <code>TypeFSRef</code> can represent existing filesystem locations only. AEDescs of <code>TypeFileURL</code> can represent both existing and non-existing locations. AEDescs of <code>TypeFSS</code> (FSSpecs) are deprecated on Mac OS X due to lack of proper Unicode and long filename support, and are retained for backwards compatibility with older applications only.</p>
|
150
|
+
|
151
|
+
|
152
|
+
|
153
|
+
|
154
|
+
<h2><code>MacTypes::FileNotFoundError</code></h2>
|
155
|
+
|
156
|
+
<p><code>FileNotFoundError</code> is a subclass of <code>RuntimeError</code>. It is raised by <code>Alias</code> and <code>FileURL</code> objects when an operation that only works for existing filesystem objects/locations fails. For example:</p>
|
157
|
+
|
158
|
+
<pre><code>require "appscript"
|
159
|
+
|
160
|
+
MacTypes::Alias.path('/some/non/existent/location')
|
161
|
+
# raises FileNotFoundError</code></pre>
|
162
|
+
|
163
|
+
|
164
|
+
<h2><code>MacTypes::Units</code></h2>
|
165
|
+
|
166
|
+
<p>The <code>Units</code> class represents a measurement of some sort, e.g. 3 inches, 98.5 degrees Fahrenheit.</p>
|
167
|
+
|
168
|
+
<pre><code>class Units
|
169
|
+
|
170
|
+
Constructor:
|
171
|
+
|
172
|
+
Units.new(value, type)
|
173
|
+
value : Fixnum | Bignum | Float -- the amount, e.g. 3.5
|
174
|
+
type : Symbol -- the unit of measurement, e.g. :centimeters
|
175
|
+
|
176
|
+
Methods:
|
177
|
+
|
178
|
+
==
|
179
|
+
|
180
|
+
hash
|
181
|
+
|
182
|
+
inspect
|
183
|
+
|
184
|
+
value -- returns the amount
|
185
|
+
|
186
|
+
type -- returns the unit of measurement
|
187
|
+
|
188
|
+
to_i -- returns the amount as an integer
|
189
|
+
|
190
|
+
to_f -- returns the amount as a float
|
191
|
+
|
192
|
+
to_s -- returns the measurement as a string, e.g. "3.5 centimeters"</code></pre>
|
193
|
+
|
194
|
+
<p>For convenience, the <code>Units</code> class also implements an additional class method, <code>Units.method_missing</code>, to allow new values to be created using the unit of measurement as the constructor call, e.g.:</p>
|
195
|
+
|
196
|
+
<pre><code>MacTypes::Units.new(14, :inches)</code></pre>
|
197
|
+
|
198
|
+
<p>can also be written as:</p>
|
199
|
+
|
200
|
+
<pre><code>MacTypes::Units.inches(14)</code></pre>
|
201
|
+
|
202
|
+
<p>See the <a href="../appscript-manual/06_classesandenums.html">Classes and Enumerated Types</a> chapter of the appscript manual for a full list of unit types built into aem/appscript. Additional application-specific unit types can be added if needed.</p>
|
203
|
+
|
204
|
+
|
205
|
+
</div>
|
206
|
+
|
207
|
+
<!-- bottom navigation -->
|
208
|
+
<div class="navbar">
|
209
|
+
<a href="index.html">Up</a>
|
210
|
+
|
211
|
+
</div>
|
212
|
+
|
213
|
+
<!--footer-->
|
214
|
+
<p class="footer">© 2006 HAS</p>
|
215
|
+
</body>
|
216
|
+
</html>
|
@@ -0,0 +1,169 @@
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
2
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
3
|
+
<head>
|
4
|
+
|
5
|
+
<title>osax</title>
|
6
|
+
|
7
|
+
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
8
|
+
<style type="text/css" media="all"><!--@import url(../appscript-manual/full.css);--></style>
|
9
|
+
|
10
|
+
</head>
|
11
|
+
<body>
|
12
|
+
|
13
|
+
<h1>osax</h1>
|
14
|
+
|
15
|
+
<!-- top navigation -->
|
16
|
+
<div class="navbar">
|
17
|
+
<a href="index.html">Up</a>
|
18
|
+
</div>
|
19
|
+
|
20
|
+
<!-- content -->
|
21
|
+
<div id="content">
|
22
|
+
<h2>What is osax?</h2>
|
23
|
+
|
24
|
+
<p>The <code>OSAX</code> module provides an easy way to call scripting additions (a.k.a. OSAXen) from Ruby. It exports a single public class, <code>ScriptingAddition</code>, and two functions, <code>osax</code> and <code>scripting_additions</code>.</p>
|
25
|
+
|
26
|
+
<p>The <code>ScriptingAddition</code> class represents a single scripting addition. It is similar to an appscript application object, except that it defines commands for the specified scripting addition instead of the application's normal commands. </p>
|
27
|
+
|
28
|
+
<p>Once you've created a <code>ScriptingAddition</code> instance, you can invoke its commands in exactly the same way as you would call a scriptable application's commands in appscript.</p>
|
29
|
+
|
30
|
+
<p>For example:</p>
|
31
|
+
|
32
|
+
<pre><code>require "osax"
|
33
|
+
|
34
|
+
sa = OSAX::ScriptingAddition.new("StandardAdditions")
|
35
|
+
|
36
|
+
sa.say("Hello world", :using=>"Victoria")</code></pre>
|
37
|
+
|
38
|
+
<p>The default application commands (<code>run</code>, <code>activate</code>, <code>quit</code>, etc.) are also available; see the appscript manual for details on those.</p>
|
39
|
+
|
40
|
+
<p>By default, <code>ScriptingAddition</code> objects are targetted at the current application. You can obtain a <code>ScriptingAddition</code> object targetted at another application by calling one of its <code>by...</code> methods.</p>
|
41
|
+
|
42
|
+
|
43
|
+
|
44
|
+
<h2><code>OSAX.scripting_additions</code></h2>
|
45
|
+
|
46
|
+
<p>The <code>scripting_additions</code> function returns the names of all installed scripting additions:</p>
|
47
|
+
|
48
|
+
<pre><code>require "osax"
|
49
|
+
|
50
|
+
p OSAX.scripting_additions
|
51
|
+
# Result: ["Digital Hub Scripting", "StandardAdditions", ...]</code></pre>
|
52
|
+
|
53
|
+
|
54
|
+
|
55
|
+
<h2><code>OSAX.osax</code></h2>
|
56
|
+
|
57
|
+
<p>The <code>osax</code> function provides a convenient shortcut for creating new <code>ScriptingAddition</code> instances:</p>
|
58
|
+
|
59
|
+
<pre><code>require "osax"
|
60
|
+
|
61
|
+
sa = OSAX.osax("StandardAdditions")
|
62
|
+
|
63
|
+
p sa
|
64
|
+
# Result: #<OSAX::ScriptingAddition
|
65
|
+
# name="StandardAdditions"
|
66
|
+
# target=AEM::Application.current></code></pre>
|
67
|
+
|
68
|
+
<p>In addition, the <code>osax</code> function accepts an application name as an optional second argument, allowing you to specify the application you want to handle the scripting addition's commands, e.g.:</p>
|
69
|
+
|
70
|
+
<pre><code>OSAX.osax("StandardAdditions", "System Events")</code></pre>
|
71
|
+
|
72
|
+
<p>is shorthand for:</p>
|
73
|
+
|
74
|
+
<pre><code>OSAX::ScriptingAddition.new("StandardAdditions").by_name("System Events")</code></pre>
|
75
|
+
|
76
|
+
<p>To specify applications by other means (e.g. URL), create a <code>ScriptingAddition</code> object first, then call the appropriate <code>by...</code> method.</p>
|
77
|
+
|
78
|
+
|
79
|
+
|
80
|
+
|
81
|
+
<h2><code>OSAX::ScriptingAddition</code></h2>
|
82
|
+
|
83
|
+
<pre><code>ScriptingAddition -- represents a single scripting addition and its
|
84
|
+
target application
|
85
|
+
|
86
|
+
Constructors:
|
87
|
+
|
88
|
+
ScriptingAddition.new(name) -- make a ScriptingAddition object
|
89
|
+
for the specified scripting addition, targetted at the
|
90
|
+
current application
|
91
|
+
|
92
|
+
Methods:
|
93
|
+
|
94
|
+
# Introspection:
|
95
|
+
|
96
|
+
commands -- returns names of all available commands
|
97
|
+
|
98
|
+
parameters(commandName) -- returns a command's parameter names
|
99
|
+
|
100
|
+
# Specifying a different target application:
|
101
|
+
|
102
|
+
# Each of the following methods returns a new ScriptingAddition
|
103
|
+
# instance targetted at the specified application. The arguments
|
104
|
+
# are the same as for the by_name, by_creator, etc. methods in
|
105
|
+
# appscript.
|
106
|
+
|
107
|
+
by_name(name) -- name or full path of application, e.g. "Finder"
|
108
|
+
|
109
|
+
by_creator(creator) -- four-character creator code, e.g. "ttxt"
|
110
|
+
|
111
|
+
by_id(id) -- bundle id, e.g. "com.apple.ical"
|
112
|
+
|
113
|
+
by_pid(pid) -- Unix process ID, e.g. 4005
|
114
|
+
|
115
|
+
by_url(url) -- eppc URL, e.g. "eppc://jukebox-mac.local/iTunes"</code></pre>
|
116
|
+
|
117
|
+
|
118
|
+
<h2>Examples</h2>
|
119
|
+
|
120
|
+
<pre><code>require "osax"
|
121
|
+
|
122
|
+
# Create a new ScriptingAddition object:
|
123
|
+
|
124
|
+
sa = OSAX.osax("StandardAdditions")
|
125
|
+
|
126
|
+
|
127
|
+
# List all available commands:
|
128
|
+
|
129
|
+
p sa.commands
|
130
|
+
# Result: ["ASCII_character", "ASCII_number", "activate", ...]
|
131
|
+
|
132
|
+
|
133
|
+
# Call some commands:
|
134
|
+
|
135
|
+
sa.beep
|
136
|
+
|
137
|
+
p sa.path_to(:scripts_folder)
|
138
|
+
# Result: MacFile::Alias.at("/Users/foo/Library/Scripts/")
|
139
|
+
|
140
|
+
p sa.display_dialog("Ruby says hello!",
|
141
|
+
:buttons=>["Hi!", "Howdy!", "Duuuude!"],
|
142
|
+
:default_button=>3)
|
143
|
+
# Result: {:button_returned=>"Howdy!"}</code></pre>
|
144
|
+
|
145
|
+
|
146
|
+
<h2>Notes</h2>
|
147
|
+
|
148
|
+
<p>When using scripting addition commands that require GUI access (e.g. <code>display_dialog</code>) targetted at the command-line Ruby interpreter, the osax module will automatically convert the non-GUI interpreter process into a full GUI process to allow these commands to operate correctly. If you want to avoid this, target these commands at a faceless GUI application such as System Events instead:</p>
|
149
|
+
|
150
|
+
<pre><code>sa = OSAX.osax("StandardAdditions", "System Events")
|
151
|
+
sa.activate # give focus to System Events
|
152
|
+
p sa.display_dialog("Ruby says hello!",
|
153
|
+
:buttons=>["Hi!", "Howdy!", "Duuuude!"],
|
154
|
+
:default_button=>3)
|
155
|
+
# Result: {:button_returned=>"Duuuude!"}</code></pre>
|
156
|
+
|
157
|
+
|
158
|
+
|
159
|
+
</div>
|
160
|
+
|
161
|
+
<!-- bottom navigation -->
|
162
|
+
<div class="navbar">
|
163
|
+
<a href="index.html">Up</a>
|
164
|
+
</div>
|
165
|
+
|
166
|
+
<!--footer-->
|
167
|
+
<p class="footer">© 2006 HAS</p>
|
168
|
+
</body>
|
169
|
+
</html>
|
data/extconf.rb
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
# appscript install script
|
2
|
+
# Based on RubyOSA extconf.rb
|
3
|
+
# Original copyright below:
|
4
|
+
#
|
5
|
+
# Copyright (c) 2006, Apple Computer, Inc. All rights reserved.
|
6
|
+
#
|
7
|
+
# Redistribution and use in source and binary forms, with or without
|
8
|
+
# modification, are permitted provided that the following conditions
|
9
|
+
# are met:
|
10
|
+
# 1. Redistributions of source code must retain the above copyright
|
11
|
+
# notice, this list of conditions and the following disclaimer.
|
12
|
+
# 2. Redistributions in binary form must reproduce the above copyright
|
13
|
+
# notice, this list of conditions and the following disclaimer in the
|
14
|
+
# documentation and/or other materials provided with the distribution.
|
15
|
+
# 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
|
16
|
+
# its contributors may be used to endorse or promote products derived
|
17
|
+
# from this software without specific prior written permission.
|
18
|
+
#
|
19
|
+
# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND
|
20
|
+
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
21
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
22
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR
|
23
|
+
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
24
|
+
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
25
|
+
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
26
|
+
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
27
|
+
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
28
|
+
# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
29
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
30
|
+
|
31
|
+
require 'mkmf'
|
32
|
+
|
33
|
+
$CFLAGS << ' -Wall'# -arch ppc -arch i386'
|
34
|
+
$LDFLAGS = '-framework Carbon'
|
35
|
+
|
36
|
+
# Avoid `ID' and `T_DATA' symbol collisions between Ruby and Carbon.
|
37
|
+
# (adapted code from RubyAEOSA - FUJIMOTO Hisakuni <hisa -at- fobj - com>)
|
38
|
+
ruby_h = "#{Config::CONFIG['archdir']}/ruby.h"
|
39
|
+
intern_h = "#{Config::CONFIG['archdir']}/intern.h"
|
40
|
+
new_filename_prefix = 'osx_'
|
41
|
+
[ ruby_h, intern_h ].each do |src_path|
|
42
|
+
dst_fname = File.join('./src', new_filename_prefix + File.basename(src_path))
|
43
|
+
$stderr.puts "create #{File.expand_path(dst_fname)} ..."
|
44
|
+
File.open(dst_fname, 'w') do |dstfile|
|
45
|
+
IO.foreach(src_path) do |line|
|
46
|
+
line = line.gsub(/\bID\b/, 'RB_ID')
|
47
|
+
line = line.gsub(/\bT_DATA\b/, 'RB_T_DATA')
|
48
|
+
line = line.gsub(/\bintern.h\b/, "#{new_filename_prefix}intern.h")
|
49
|
+
dstfile.puts line
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
create_makefile('ae', 'src')
|
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/local/bin/ruby
|
2
|
+
# Copyright (C) 2006 HAS.
|
3
|
+
# Released under MIT License.
|
4
|
+
|
5
|
+
AdobeUnitTypes = [
|
6
|
+
[:millimeters, "\x81MM\x8c"],
|
7
|
+
[:points, "\x81PS\x8c"],
|
8
|
+
[:picas, "\x81SP\x8c"],
|
9
|
+
[:traditional_points, "\x81PT\x8c"],
|
10
|
+
[:traditional_picas, "\x81PC\x8c"],
|
11
|
+
[:ciceros, "\x81CR\x8c"],
|
12
|
+
[:percent, "\x81PN\x8c"],
|
13
|
+
[:pixels, "\x81PX\x8c"],
|
14
|
+
]
|
data/misc/dump.rb
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
#!/usr/local/bin/ruby
|
2
|
+
# Copyright (C) 2006 HAS.
|
3
|
+
# Released under MIT License.
|
4
|
+
|
5
|
+
require "ae"
|
6
|
+
require "aem"
|
7
|
+
require "findapp"
|
8
|
+
require "_appscript/terminology"
|
9
|
+
|
10
|
+
if ARGV.length != 3
|
11
|
+
puts "dump.rb
|
12
|
+
|
13
|
+
Outputs an application's terminology as a Ruby module file, suitable for use by AS::Application.
|
14
|
+
|
15
|
+
Usage:
|
16
|
+
|
17
|
+
ruby dump.rb application-name-or-path module-name module-path
|
18
|
+
|
19
|
+
Example:
|
20
|
+
|
21
|
+
ruby dump.rb Address\ Book AddressBook ~/addressbook_terms.rb"
|
22
|
+
|
23
|
+
exit
|
24
|
+
end
|
25
|
+
|
26
|
+
app_path = FindApp.by_name(ARGV[0])
|
27
|
+
module_name = ARGV[1]
|
28
|
+
out_path = ARGV[2]
|
29
|
+
|
30
|
+
if not /^[A-Z][A-Za-z0-9_]*$/ === module_name
|
31
|
+
raise RuntimeError, "Invalid module name."
|
32
|
+
end
|
33
|
+
|
34
|
+
File.open(out_path, "w") do |f|
|
35
|
+
# Get aete(s)
|
36
|
+
begin
|
37
|
+
aetes = AEM::Codecs.new.unpack(AE.get_app_terminology(app_path).coerce(KAE::TypeAEList))
|
38
|
+
rescue AE::MacOSError => e
|
39
|
+
if e.to_i == -192 # aete resource not found
|
40
|
+
raise RuntimeError, "No terminology found."
|
41
|
+
else
|
42
|
+
raise
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# Parse aete(s) into intermediate tables, suitable for use by Terminology#tables_for_module
|
47
|
+
tables = TerminologyParser.build_tables_for_aetes(aetes)
|
48
|
+
|
49
|
+
# Write module code
|
50
|
+
f.puts "module #{module_name}"
|
51
|
+
f.puts "\tVersion = 1.1"
|
52
|
+
f.puts "\tPath = #{app_path.inspect}"
|
53
|
+
f.puts
|
54
|
+
(["Classes", "Enumerators", "Properties", "Elements"].zip(tables[0,4])).each do |name, table|
|
55
|
+
f.puts "\t#{name} = ["
|
56
|
+
table.sort.each do |item|
|
57
|
+
f.puts "\t\t#{item.inspect},"
|
58
|
+
end
|
59
|
+
f.puts "\t]"
|
60
|
+
f.puts
|
61
|
+
end
|
62
|
+
f.puts "\tCommands = ["
|
63
|
+
tables[4].sort.each do |name, code, params|
|
64
|
+
f.puts "\t\t[#{name.inspect}, #{code.inspect}, ["
|
65
|
+
params.each do |item|
|
66
|
+
f.puts "\t\t\t#{item.inspect},"
|
67
|
+
end
|
68
|
+
f.puts "\t\t]],"
|
69
|
+
end
|
70
|
+
f.puts "\t]"
|
71
|
+
f.puts "end"
|
72
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
|
3
|
+
spec = Gem::Specification.new do |s|
|
4
|
+
s.name = "rb-appscript"
|
5
|
+
s.version = "0.2.0"
|
6
|
+
s.author = "HAS"
|
7
|
+
s.homepage = "http://rb-appscript.rubyforge.org/"
|
8
|
+
s.rubyforge_project="rb-appscript"
|
9
|
+
s.summary="Ruby appscript (rb-appscript) is a high-level, user-friendly Apple event bridge that allows you to control scriptable Mac OS X applications using ordinary Ruby scripts."
|
10
|
+
s.files = Dir["**/*"].delete_if { |name| ["MakeFile", "ae.bundle", "mkmf.log", "rbae.o", "src/osx_ruby.h", "src/osx_intern.h"].include?(name) }
|
11
|
+
s.extensions = "extconf.rb"
|
12
|
+
s.test_files = Dir["test/test_*.rb"]
|
13
|
+
s.required_ruby_version = ">= 1.8"
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
if $0==__FILE__
|
18
|
+
Gem::manage_gems
|
19
|
+
Gem::Builder.new(spec).build
|
20
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# Lists the name and email(s) of every person in Address Book with one or more email addresses.
|
4
|
+
|
5
|
+
require "appscript"
|
6
|
+
|
7
|
+
people_ref = AS.app('Address Book').people[AS.its.emails.ne([])]
|
8
|
+
p people_ref.name.get.zip(people_ref.emails.value.get)
|
@@ -0,0 +1,72 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# Creates daily recurring todo items in iCal.
|
4
|
+
#
|
5
|
+
# Ported from 'Create daily todos.scpt' by Alexander Kellett
|
6
|
+
# <http://web.mac.com/lypanov>
|
7
|
+
#
|
8
|
+
# While iCal makes it easy to create recurring events, it lacks a similar
|
9
|
+
# feature for To Do items. This script can be used to create a daily checklist
|
10
|
+
# of things to do.
|
11
|
+
#
|
12
|
+
# To begin, create a new calendar with the name "Shadow". Then, add a number
|
13
|
+
# of recurring events to this calendar. All Daily To Dos events must be
|
14
|
+
# recurring events as only recurring events are converted to To Dos. Start and
|
15
|
+
# end dates are ignored.
|
16
|
+
#
|
17
|
+
# Now, create a calendar called "Personal". When the script is run, all the
|
18
|
+
# To Do items will be added to this calendar. Finally, set up a cron job to
|
19
|
+
# run this script first thing every morning.
|
20
|
+
#
|
21
|
+
# See also:
|
22
|
+
# <http://web.mac.com/lypanov/iWeb/Web/Diary/1EDF1B30-C4AF-4A99-BC4D-
|
23
|
+
# 4A8AF14BFC96.html>
|
24
|
+
# <http://web.mac.com/lypanov/iWeb/Web/Diary/9950DF91-726E-42B2-A639-
|
25
|
+
# 1967D1DE7545.html>
|
26
|
+
|
27
|
+
|
28
|
+
require "appscript"
|
29
|
+
|
30
|
+
ICal = AS.app("iCal")
|
31
|
+
|
32
|
+
# The calendar in which recurring todo items should appear:
|
33
|
+
ToDoCalendarName = "Personal"
|
34
|
+
|
35
|
+
def create_to_do(summary_text)
|
36
|
+
# Adds To Dos to calendar "Personal"
|
37
|
+
now = Time.new
|
38
|
+
midnight = Time.local(now.year(), now.month(), now.day())
|
39
|
+
to_dos = ICal.calendars[ToDoCalendarName].todos
|
40
|
+
# don't create an item if it already exists for today!
|
41
|
+
if to_dos[AS.its.due_date.ge(midnight).and(
|
42
|
+
AS.its.summary.eq(summary_text))].count < 1
|
43
|
+
to_dos.end.make(:new=>:todo, :with_properties=>{
|
44
|
+
:due_date=>midnight, :summary=>summary_text})
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def get_label(recurrence, label)
|
49
|
+
match = Regexp.new("(?:^|;)#{label}=(.*?)(?:$|;)").match(recurrence)
|
50
|
+
return match ? match[1] : nil
|
51
|
+
end
|
52
|
+
|
53
|
+
weekday_code = ["SU", "MO", "TU", "WE", "TH", "FR", "SA"][Time.new.wday]
|
54
|
+
events = ICal.calendars["Shadow"].events
|
55
|
+
|
56
|
+
events.recurrence.get.zip(events.summary.get).each do |recurrence, summary|
|
57
|
+
recurs_on_this_weekday = false
|
58
|
+
frequency = get_label(recurrence, "FREQ")
|
59
|
+
case frequency
|
60
|
+
when "WEEKLY"
|
61
|
+
days = get_label(recurrence, "BYDAY")
|
62
|
+
if days and days.split(",").include?(weekday_code)
|
63
|
+
recurs_on_this_weekday = true
|
64
|
+
end
|
65
|
+
when "DAILY"
|
66
|
+
recurs_on_this_weekday = true
|
67
|
+
end
|
68
|
+
if recurs_on_this_weekday
|
69
|
+
puts summary
|
70
|
+
create_to_do(summary)
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# Compose an outgoing message in Apple's Mail.app.
|
4
|
+
|
5
|
+
require "appscript"
|
6
|
+
|
7
|
+
def make_message(addresses, subject, content, show_window=false)
|
8
|
+
# Make an outgoing message in Mail.
|
9
|
+
# addresses : list of unicode -- a list of email addresses
|
10
|
+
# subject : unicode -- the message subject
|
11
|
+
# content : unicode -- the message content
|
12
|
+
# show_window : Boolean -- show message window in Mail
|
13
|
+
# Result : reference -- reference to the new outgoing message
|
14
|
+
mail = AS.app('Mail')
|
15
|
+
msg = mail.make(
|
16
|
+
:new => :outgoing_message,
|
17
|
+
:with_properties => {:visible => show_window})
|
18
|
+
addresses.each do |an_address|
|
19
|
+
msg.to_recipients.end.make(
|
20
|
+
:new => :recipient,
|
21
|
+
:with_properties => {:address => an_address})
|
22
|
+
end
|
23
|
+
msg.subject.set(subject)
|
24
|
+
msg.content.set(content)
|
25
|
+
return msg
|
26
|
+
end
|
27
|
+
|
28
|
+
# test
|
29
|
+
p make_message(['joe@foo.com', 'jane@bar.net'], 'Hello World', 'Some body text.', true)
|