rb-appscript 0.5.3 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES +28 -0
- data/README +51 -31
- data/doc/aem-manual/01_introduction.html +0 -2
- data/doc/aem-manual/02_apioverview.html +13 -9
- data/doc/aem-manual/03_packingandunpackingdata.html +41 -9
- data/doc/aem-manual/04_references.html +42 -40
- data/doc/aem-manual/{05_targettingapplications.html → 05_targetingapplications.html} +4 -6
- data/doc/aem-manual/06_buildingandsendingevents.html +40 -12
- data/doc/aem-manual/07_findapp.html +0 -2
- data/doc/aem-manual/08_examples.html +0 -2
- data/doc/aem-manual/aemreferenceinheritance.gif +0 -0
- data/doc/aem-manual/index.html +1 -3
- data/doc/appscript-manual/01_introduction.html +0 -2
- data/doc/appscript-manual/02_aboutappscripting.html +4 -6
- data/doc/appscript-manual/03_quicktutorial.html +1 -3
- data/doc/appscript-manual/04_gettinghelp.html +20 -7
- data/doc/appscript-manual/05_keywordconversion.html +5 -3
- data/doc/appscript-manual/06_classesandenums.html +32 -8
- data/doc/appscript-manual/07_applicationobjects.html +30 -41
- data/doc/appscript-manual/08_realvsgenericreferences.html +0 -2
- data/doc/appscript-manual/09_referenceforms.html +0 -2
- data/doc/appscript-manual/10_referenceexamples.html +1 -3
- data/doc/appscript-manual/11_applicationcommands.html +29 -2
- data/doc/appscript-manual/12_commandexamples.html +0 -2
- data/doc/appscript-manual/13_performanceissues.html +0 -2
- data/doc/appscript-manual/14_notes.html +0 -19
- data/doc/appscript-manual/index.html +0 -2
- data/doc/index.html +1 -4
- data/doc/mactypes-manual/01_introduction.html +0 -2
- data/doc/mactypes-manual/02_aliasclass.html +0 -10
- data/doc/mactypes-manual/03_fileurlclass.html +1 -11
- data/doc/mactypes-manual/04_unitsclass.html +0 -2
- data/doc/mactypes-manual/index.html +0 -2
- data/doc/osax-manual/01_introduction.html +0 -2
- data/doc/osax-manual/02_interface.html +0 -2
- data/doc/osax-manual/03_examples.html +0 -2
- data/doc/osax-manual/04_notes.html +6 -25
- data/doc/osax-manual/index.html +0 -2
- data/rb-appscript.gemspec +2 -3
- data/sample/AB_export_vcard.rb +0 -0
- data/sample/AB_list_people_with_emails.rb +0 -0
- data/sample/Create_daily_iCal_todos.rb +0 -0
- data/sample/Export_Address_Book_phone_numbers.rb +0 -0
- data/sample/Hello_world.rb +0 -0
- data/sample/List_iTunes_playlist_names.rb +0 -0
- data/sample/Open_file_in_TextEdit.rb +0 -0
- data/sample/Organize_Mail_messages.rb +0 -0
- data/sample/TextEdit_demo.rb +0 -0
- data/sample/iTunes_top40_to_html.rb +0 -0
- data/src/SendThreadSafe.c +0 -0
- data/src/SendThreadSafe.h +0 -0
- data/src/lib/_aem/aemreference.rb +5 -7
- data/src/lib/_aem/codecs.rb +47 -24
- data/src/lib/_aem/connect.rb +29 -8
- data/src/lib/_aem/encodingsupport.rb +77 -0
- data/src/lib/_aem/findapp.rb +0 -2
- data/src/lib/_aem/mactypes.rb +0 -2
- data/src/lib/_aem/send.rb +6 -8
- data/src/lib/_aem/typewrappers.rb +0 -2
- data/src/lib/_appscript/defaultterminology.rb +0 -2
- data/src/lib/_appscript/referencerenderer.rb +1 -3
- data/src/lib/_appscript/reservedkeywords.rb +0 -2
- data/src/lib/_appscript/safeobject.rb +58 -9
- data/src/lib/_appscript/terminology.rb +63 -46
- data/src/lib/aem.rb +3 -4
- data/src/lib/appscript.rb +12 -13
- data/src/lib/osax.rb +436 -9
- data/src/rbae.c +126 -103
- data/test/test_aemreference.rb +0 -0
- data/test/test_appscriptcommands.rb +15 -1
- data/test/test_appscriptreference.rb +0 -0
- data/test/test_codecs.rb +10 -4
- data/test/test_findapp.rb +0 -0
- data/test/test_mactypes.rb +0 -0
- data/test/test_osax.rb +0 -0
- data/test/testall.sh +0 -0
- metadata +24 -24
- data/LICENSE +0 -70
- data/TODO +0 -19
data/src/lib/_aem/connect.rb
CHANGED
@@ -3,8 +3,6 @@
|
|
3
3
|
#
|
4
4
|
# connect -- launch applications and create AEAddressDescs
|
5
5
|
#
|
6
|
-
# Copyright (C) 2006-2009 HAS. Released under MIT License.
|
7
|
-
#
|
8
6
|
|
9
7
|
module Connect
|
10
8
|
# Creates Apple event descriptor records of typeProcessSerialNumber, typeKernelProcessID and typeApplicationURL, used to specify the target application in Send::Event constructor.
|
@@ -13,10 +11,28 @@ module Connect
|
|
13
11
|
require "kae"
|
14
12
|
require "_aem/codecs"
|
15
13
|
require "_aem/send"
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
14
|
+
require "_aem/encodingsupport"
|
15
|
+
|
16
|
+
@@encoding_support = AEMEncodingSupport.encoding_support
|
17
|
+
|
18
|
+
LSLaunchDefaults = 0x00000001
|
19
|
+
LSLaunchAndPrint = 0x00000002
|
20
|
+
LSLaunchReserved2 = 0x00000004
|
21
|
+
LSLaunchReserved3 = 0x00000008
|
22
|
+
LSLaunchReserved4 = 0x00000010
|
23
|
+
LSLaunchReserved5 = 0x00000020
|
24
|
+
LSLaunchAndDisplayErrors = 0x00000040
|
25
|
+
LSLaunchInhibitBGOnly = 0x00000080
|
26
|
+
LSLaunchDontAddToRecents = 0x00000100
|
27
|
+
LSLaunchDontSwitch = 0x00000200
|
28
|
+
LSLaunchNoParams = 0x00000800
|
29
|
+
LSLaunchAsync = 0x00010000
|
30
|
+
LSLaunchStartClassic = 0x00020000
|
31
|
+
LSLaunchInClassic = 0x00040000
|
32
|
+
LSLaunchNewInstance = 0x00080000
|
33
|
+
LSLaunchAndHide = 0x00100000
|
34
|
+
LSLaunchAndHideOthers = 0x00200000
|
35
|
+
LSLaunchHasUntrustedContents = 0x00400000
|
20
36
|
|
21
37
|
KNoProcess = 0
|
22
38
|
KCurrentProcess = 2
|
@@ -65,9 +81,10 @@ module Connect
|
|
65
81
|
##
|
66
82
|
|
67
83
|
def Connect.launch_application(path, event)
|
84
|
+
path = @@encoding_support.to_utf8_string(path)
|
68
85
|
begin
|
69
86
|
return AE.launch_application(path, event,
|
70
|
-
|
87
|
+
LSLaunchNoParams | LSLaunchStartClassic | LSLaunchDontSwitch)
|
71
88
|
rescue AE::MacOSError => err
|
72
89
|
raise CantLaunchApplicationError, err.to_i
|
73
90
|
end
|
@@ -75,6 +92,7 @@ module Connect
|
|
75
92
|
|
76
93
|
def Connect.launch_app_with_launch_event(path)
|
77
94
|
# Send a 'launch' event to an application. If application is not already running, it will be launched in background first.
|
95
|
+
path = @@encoding_support.to_utf8_string(path)
|
78
96
|
begin
|
79
97
|
# If app is already running, calling AE.launch_application will send a 'reopen' event, so need to check for this first:
|
80
98
|
psn = AE.psn_for_application_path(path)
|
@@ -93,6 +111,7 @@ module Connect
|
|
93
111
|
##
|
94
112
|
|
95
113
|
def Connect.process_exists_for_path?(path)
|
114
|
+
path = @@encoding_support.to_utf8_string(path)
|
96
115
|
# Does a local process launched from the specified application file exist?
|
97
116
|
# Note: if path is invalid, an AE::MacOSError is raised.
|
98
117
|
begin
|
@@ -138,7 +157,7 @@ module Connect
|
|
138
157
|
# AESendMessage may return a timeout error (this should be -1712, but
|
139
158
|
# -609 is often returned instead for some reason).
|
140
159
|
Send::Event.new(desc, 'ascrnoop').send
|
141
|
-
rescue Send::
|
160
|
+
rescue Send::EventError => err
|
142
161
|
return (not [-600, -905].include?(err.to_i)) # not running/no network access
|
143
162
|
end
|
144
163
|
return true
|
@@ -154,6 +173,7 @@ module Connect
|
|
154
173
|
# Result : AEAddressDesc
|
155
174
|
#
|
156
175
|
# Always creates AEAddressDesc by process serial number; that way there's no confusion if multiple versions of the same app are running.
|
176
|
+
path = @@encoding_support.to_utf8_string(path)
|
157
177
|
begin
|
158
178
|
psn = AE.psn_for_application_path(path)
|
159
179
|
rescue AE::MacOSError => err
|
@@ -175,6 +195,7 @@ module Connect
|
|
175
195
|
end
|
176
196
|
|
177
197
|
def Connect.remote_app(url)
|
198
|
+
url = @@encoding_support.to_utf8_string(url)
|
178
199
|
# Make an AEAddressDesc identifying a running application on another machine.
|
179
200
|
# url : string -- URL for remote application, e.g. 'eppc://user:password@0.0.0.1/TextEdit'
|
180
201
|
# Result : AEAddressDesc
|
@@ -0,0 +1,77 @@
|
|
1
|
+
#
|
2
|
+
# rb-appscript
|
3
|
+
#
|
4
|
+
# encodingsupport -- support string encodings in Ruby 1.9+
|
5
|
+
#
|
6
|
+
|
7
|
+
|
8
|
+
module AEMEncodingSupport
|
9
|
+
|
10
|
+
module EnableStringEncodings
|
11
|
+
# AE extension methods consume and return Strings containing UTF-8 encoded data, ignoring
|
12
|
+
# any attached encoding information. This module provides wrappers for AE interactions that
|
13
|
+
# take care of any encoding issues in Ruby 1.9+.
|
14
|
+
|
15
|
+
def EnableStringEncodings.to_utf8_string(s)
|
16
|
+
# Call before passing a string to an AE method that expects it to contain UTF-8 encoded data.
|
17
|
+
return s if [Encoding::ASCII_8BIT, Encoding::UTF_8].include?(s.encoding)
|
18
|
+
return s.encode('UTF-8')
|
19
|
+
end
|
20
|
+
|
21
|
+
def EnableStringEncodings.pack_string(s, as_type)
|
22
|
+
begin
|
23
|
+
return AE::AEDesc.new(KAE::TypeUTF8Text, EnableStringEncodings.to_utf8_string(s)).coerce(as_type)
|
24
|
+
rescue AE::MacOSError => e
|
25
|
+
if e.to_i == -1700 # couldn't coerce to TypeUnicodeText
|
26
|
+
raise TypeError, "Not valid UTF8 data or couldn't coerce to type %{as_type}: #{s.inspect}"
|
27
|
+
else
|
28
|
+
raise
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def EnableStringEncodings.unpack_string(desc)
|
34
|
+
# String instances returned by AE methods contain UTF-8 data and ASCII-8BIT encoding,
|
35
|
+
# so change the encoding to match the data
|
36
|
+
return desc.coerce(KAE::TypeUTF8Text).data.force_encoding('UTF-8')
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
module DisableStringEncodings
|
42
|
+
# Support for Ruby 1.8 Strings, which do not contain encoding information. User is responsible
|
43
|
+
# for ensuring String instances passed to AE APIs contain UTF-8 encoded data; String instances
|
44
|
+
# returned by unpack_string will always contain contain UTF-8 encoded data.
|
45
|
+
|
46
|
+
def DisableStringEncodings.to_utf8_string(s)
|
47
|
+
return s
|
48
|
+
end
|
49
|
+
|
50
|
+
def DisableStringEncodings.pack_string(s, as_type)
|
51
|
+
begin
|
52
|
+
# Note: while the BOM is optional in typeUnicodeText, it's not included by AS
|
53
|
+
# and some apps, e.g. iTunes 7, will handle it incorrectly, so it's omitted here.)
|
54
|
+
return AE::AEDesc.new(KAE::TypeUTF8Text, s).coerce(as_type)
|
55
|
+
rescue AE::MacOSError => e
|
56
|
+
if e.to_i == -1700 # couldn't coerce to TypeUnicodeText
|
57
|
+
raise TypeError, "Not valid UTF8 data or couldn't coerce to type %{as_type}: #{s.inspect}"
|
58
|
+
else
|
59
|
+
raise
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def DisableStringEncodings.unpack_string(desc)
|
65
|
+
return desc.coerce(KAE::TypeUTF8Text).data
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
|
71
|
+
def AEMEncodingSupport.encoding_support
|
72
|
+
# get the appropriate module for the Ruby version used
|
73
|
+
version, sub_version = RUBY_VERSION.split('.').collect {|n| n.to_i} [0, 2]
|
74
|
+
return (version >= 1 and sub_version >= 9) ? AEMEncodingSupport::EnableStringEncodings : AEMEncodingSupport::DisableStringEncodings
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
data/src/lib/_aem/findapp.rb
CHANGED
@@ -3,8 +3,6 @@
|
|
3
3
|
#
|
4
4
|
# findapp -- locate an application by name, bundle ID or creator code
|
5
5
|
#
|
6
|
-
# Copyright (C) 2006-2009 HAS. Released under MIT License.
|
7
|
-
#
|
8
6
|
|
9
7
|
module FindApp
|
10
8
|
# Support module for obtaining the full path to a local application given its name, bundle id or creator type. If application isn't found, an ApplicationNotFoundError exception is raised.
|
data/src/lib/_aem/mactypes.rb
CHANGED
data/src/lib/_aem/send.rb
CHANGED
@@ -3,13 +3,11 @@
|
|
3
3
|
#
|
4
4
|
# send -- Event class represents a packed AppleEvent that's ready to send via AESendMessage
|
5
5
|
#
|
6
|
-
# Copyright (C) 2006-2009 HAS. Released under MIT License.
|
7
|
-
#
|
8
6
|
|
9
7
|
module Send
|
10
8
|
|
11
9
|
# Defines the Event class, which represents an Apple event that's packed and ready to send,
|
12
|
-
# and the
|
10
|
+
# and the EventError class, which contains error information for a failed event.
|
13
11
|
|
14
12
|
require "ae"
|
15
13
|
require "kae"
|
@@ -73,7 +71,7 @@ module Send
|
|
73
71
|
reply_event = _send_apple_event(flags, timeout)
|
74
72
|
rescue AE::MacOSError => err # The Apple Event Manager raised an error.
|
75
73
|
if not(@_event_code == 'aevtquit' and err.to_i == -609) # Ignore invalid connection errors (-609) when quitting
|
76
|
-
raise
|
74
|
+
raise EventError.new(err.to_i)
|
77
75
|
end
|
78
76
|
else # Decode application's reply, if any. May be a return value, error number (and optional message), or nothing.
|
79
77
|
if reply_event.type != KAE::TypeNull
|
@@ -86,7 +84,7 @@ module Send
|
|
86
84
|
# Error info is unpacked using default codecs for reliability.
|
87
85
|
e_num = DefaultCodecs.unpack(event_result[KAE::KeyErrorNumber])
|
88
86
|
if e_num != 0 # Some apps (e.g. Finder) may return error code 0 to indicate a successful operation, so ignore this.
|
89
|
-
raise
|
87
|
+
raise EventError.new(e_num, event_result)
|
90
88
|
end
|
91
89
|
end
|
92
90
|
if event_result.has_key?(KAE::KeyAEResult)
|
@@ -101,7 +99,7 @@ module Send
|
|
101
99
|
end
|
102
100
|
|
103
101
|
|
104
|
-
class
|
102
|
+
class EventError < RuntimeError
|
105
103
|
# Represents an error raised by the Apple Event Manager or target application when a command fails.
|
106
104
|
#
|
107
105
|
# Methods:
|
@@ -255,9 +253,9 @@ module Send
|
|
255
253
|
|
256
254
|
def to_s
|
257
255
|
if message != ''
|
258
|
-
return "
|
256
|
+
return "EventError\n\t\tOSERROR: #{number}\n\t\tMESSAGE: #{message}"
|
259
257
|
else
|
260
|
-
return "
|
258
|
+
return "EventError\n\t\tOSERROR: #{number}"
|
261
259
|
end
|
262
260
|
end
|
263
261
|
|
@@ -3,8 +3,6 @@
|
|
3
3
|
#
|
4
4
|
# defaultterminology -- lookup tables for default type, enumerator and command definitions
|
5
5
|
#
|
6
|
-
# Copyright (C) 2006-2009 HAS. Released under MIT License.
|
7
|
-
#
|
8
6
|
|
9
7
|
module DefaultTerminology
|
10
8
|
# Defines built-in terminology available for any application. When constructing the terminology tables for a particular application, the Terminology module will duplicate these tables and then add application-specific terms to create the finished lookup tables.
|
@@ -3,8 +3,6 @@
|
|
3
3
|
#
|
4
4
|
# referencerenderer -- obtain an appscript-style string representation of an aem reference
|
5
5
|
#
|
6
|
-
# Copyright (C) 2006-2009 HAS. Released under MIT License.
|
7
|
-
#
|
8
6
|
|
9
7
|
require "_aem/aemreference"
|
10
8
|
|
@@ -21,7 +19,7 @@ class ReferenceRenderer
|
|
21
19
|
end
|
22
20
|
|
23
21
|
def _format(val)
|
24
|
-
if val.is_a?(AEMReference::
|
22
|
+
if val.is_a?(AEMReference::Query)
|
25
23
|
return ReferenceRenderer.render(@_app_data, val)
|
26
24
|
else
|
27
25
|
return val.inspect
|
@@ -4,8 +4,6 @@
|
|
4
4
|
# reservedkeywords -- names of methods already used by Ruby's Object class
|
5
5
|
# and appscript's Reference class
|
6
6
|
#
|
7
|
-
# Copyright (C) 2006-2009 HAS. Released under MIT License.
|
8
|
-
#
|
9
7
|
|
10
8
|
# This list is mirrored in ch.6 of the appscript manual and in py-osaterminology's makeidentifier module
|
11
9
|
|
@@ -3,7 +3,6 @@
|
|
3
3
|
#
|
4
4
|
# safeobject -- ensure Appscript::Reference#method_missing works reliably
|
5
5
|
#
|
6
|
-
# New code Copyright (C) 2006-2009 HAS
|
7
6
|
# Original code Copyright (C) 2005 Thomas Sawyer, Jim Weirich; see below for original copyright
|
8
7
|
#
|
9
8
|
|
@@ -60,14 +59,64 @@
|
|
60
59
|
#
|
61
60
|
# == Copyright (c) 2005 Thomas Sawyer, Jim Weirich
|
62
61
|
#
|
63
|
-
#
|
64
|
-
#
|
65
|
-
#
|
66
|
-
#
|
67
|
-
#
|
68
|
-
#
|
69
|
-
#
|
70
|
-
#
|
62
|
+
# THE RUBY LICENSE
|
63
|
+
# (http://www.ruby-lang.org/en/LICENSE.txt)
|
64
|
+
#
|
65
|
+
# You may redistribute this software and/or modify it under either the terms of
|
66
|
+
# the GPL (see below), or the conditions below:
|
67
|
+
#
|
68
|
+
# 1. You may make and give away verbatim copies of the source form of the
|
69
|
+
# software without restriction, provided that you duplicate all of the
|
70
|
+
# original copyright notices and associated disclaimers.
|
71
|
+
#
|
72
|
+
# 2. You may modify your copy of the software in any way, provided that
|
73
|
+
# you do at least ONE of the following:
|
74
|
+
#
|
75
|
+
# a) place your modifications in the Public Domain or otherwise
|
76
|
+
# make them Freely Available, such as by posting said
|
77
|
+
# modifications to Usenet or an equivalent medium, or by allowing
|
78
|
+
# the author to include your modifications in the software.
|
79
|
+
#
|
80
|
+
# b) use the modified software only within your corporation or
|
81
|
+
# organization.
|
82
|
+
#
|
83
|
+
# c) rename any non-standard executables so the names do not conflict
|
84
|
+
# with standard executables, which must also be provided.
|
85
|
+
#
|
86
|
+
# d) make other distribution arrangements with the author.
|
87
|
+
#
|
88
|
+
# 3. You may distribute the software in object code or executable
|
89
|
+
# form, provided that you do at least ONE of the following:
|
90
|
+
#
|
91
|
+
# a) distribute the executables and library files of the software,
|
92
|
+
# together with instructions (in the manual page or equivalent)
|
93
|
+
# on where to get the original distribution.
|
94
|
+
#
|
95
|
+
# b) accompany the distribution with the machine-readable source of
|
96
|
+
# the software.
|
97
|
+
#
|
98
|
+
# c) give non-standard executables non-standard names, with
|
99
|
+
# instructions on where to get the original software distribution.
|
100
|
+
#
|
101
|
+
# d) make other distribution arrangements with the author.
|
102
|
+
#
|
103
|
+
# 4. You may modify and include the part of the software into any other
|
104
|
+
# software (possibly commercial). But some files in the distribution
|
105
|
+
# are not written by the author, so that they are not under these terms.
|
106
|
+
#
|
107
|
+
# For the list of those files and their copying conditions, see the
|
108
|
+
# file LEGAL.
|
109
|
+
#
|
110
|
+
# 5. The scripts and library files supplied as input to or produced as
|
111
|
+
# output from the software do not automatically fall under the
|
112
|
+
# copyright of the software, but belong to whomever generated them,
|
113
|
+
# and may be sold commercially, and may be aggregated with this
|
114
|
+
# software.
|
115
|
+
#
|
116
|
+
# 6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
|
117
|
+
# IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
118
|
+
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
119
|
+
# PURPOSE.
|
71
120
|
|
72
121
|
######################################################################
|
73
122
|
# PUBLIC
|
@@ -3,8 +3,6 @@
|
|
3
3
|
#
|
4
4
|
# terminology -- retrieve and convert an application's terminology into lookup tables
|
5
5
|
#
|
6
|
-
# Copyright (C) 2006-2009 HAS. Released under MIT License.
|
7
|
-
#
|
8
6
|
|
9
7
|
######################################################################
|
10
8
|
# TERMINOLOGY PARSER
|
@@ -339,6 +337,38 @@ module Terminology
|
|
339
337
|
return reference_by_code, reference_by_name
|
340
338
|
end
|
341
339
|
|
340
|
+
def Terminology.dump_tables(tables, module_name, source_path, out_path)
|
341
|
+
# Parse aete(s) into intermediate tables, suitable for use by Terminology#tables_for_module
|
342
|
+
if not(/^[A-Z][A-Za-z0-9_]*$/ === module_name)
|
343
|
+
raise RuntimeError, "Invalid module name."
|
344
|
+
end
|
345
|
+
# Write module
|
346
|
+
File.open(out_path, "w") do |f|
|
347
|
+
f.puts "module #{module_name}"
|
348
|
+
f.puts "\tVersion = 1.1"
|
349
|
+
f.puts "\tPath = #{source_path.inspect}"
|
350
|
+
f.puts
|
351
|
+
(["Classes", "Enumerators", "Properties", "Elements"].zip(tables[0,4])).each do |name, table|
|
352
|
+
f.puts "\t#{name} = ["
|
353
|
+
table.sort.each do |item|
|
354
|
+
f.puts "\t\t#{item.inspect},"
|
355
|
+
end
|
356
|
+
f.puts "\t]"
|
357
|
+
f.puts
|
358
|
+
end
|
359
|
+
f.puts "\tCommands = ["
|
360
|
+
tables[4].sort.each do |name, code, params|
|
361
|
+
f.puts "\t\t[#{name.inspect}, #{code.inspect}, ["
|
362
|
+
params.each do |item|
|
363
|
+
f.puts "\t\t\t#{item.inspect},"
|
364
|
+
end
|
365
|
+
f.puts "\t\t]],"
|
366
|
+
end
|
367
|
+
f.puts "\t]"
|
368
|
+
f.puts "end"
|
369
|
+
end
|
370
|
+
end
|
371
|
+
|
342
372
|
#######
|
343
373
|
# public
|
344
374
|
|
@@ -367,11 +397,18 @@ module Terminology
|
|
367
397
|
+ _make_reference_table(terms::Properties, terms::Elements, terms::Commands)
|
368
398
|
end
|
369
399
|
|
400
|
+
def Terminology.tables_for_parsed_sdef(terms)
|
401
|
+
# Build terminology tables from an SdefParser instance.
|
402
|
+
# Result : list of hash -- [typebycode, typebyname, referencebycode, referencebyname]
|
403
|
+
return _make_type_table(terms.classes, terms.enumerators, terms.properties) \
|
404
|
+
+ _make_reference_table(terms.properties, terms.elements, terms.commands)
|
405
|
+
end
|
406
|
+
|
370
407
|
def Terminology.aetes_for_app(aem_app)
|
371
408
|
begin
|
372
409
|
begin
|
373
410
|
aetes = aem_app.event('ascrgdte', {'----' => 0}).send(120 * 60)
|
374
|
-
rescue AEM::
|
411
|
+
rescue AEM::EventError => e
|
375
412
|
if e.number == -192 # aete resource not found
|
376
413
|
aetes = []
|
377
414
|
else
|
@@ -397,58 +434,38 @@ module Terminology
|
|
397
434
|
end
|
398
435
|
|
399
436
|
#######
|
437
|
+
# public
|
400
438
|
|
401
439
|
def Terminology.dump(app_name, module_name, out_path)
|
402
|
-
# Export terminology tables as a Ruby module
|
440
|
+
# Export application terminology tables as a Ruby module
|
403
441
|
# app_path : string -- name or path of application
|
404
442
|
# module_name : string -- name of generated module (must be a valid Ruby constant)
|
405
443
|
# out_path : string -- module file to write
|
444
|
+
#
|
445
|
+
# Generates a Ruby module containing an application's basic terminology
|
446
|
+
# (names and codes) as used by appscript.
|
447
|
+
#
|
448
|
+
# Call the #dump method to dump faulty aetes to Ruby module, e.g.:
|
449
|
+
#
|
450
|
+
# Terminology.dump('MyApp', 'MyAppGlue', '/path/to/ruby/modules/myappglue.rb')
|
451
|
+
#
|
452
|
+
# Patch any errors by hand, then import the patched module into your script
|
453
|
+
# and pass it to appscript's app() constructor via its 'terms' argument, e.g.:
|
454
|
+
#
|
455
|
+
# require 'appscript'; include Appscript
|
456
|
+
# require 'myappglue'
|
457
|
+
#
|
458
|
+
# myapp = app('MyApp', terms => MyAppGlue)
|
459
|
+
#
|
460
|
+
# Note that dumped terminologies aren't used by appscript's built-in help system.
|
461
|
+
#
|
406
462
|
app_path = FindApp.by_name(app_name)
|
407
|
-
if not(/^[A-Z][A-Za-z0-9_]*$/ === module_name)
|
408
|
-
raise RuntimeError, "Invalid module name."
|
409
|
-
end
|
410
463
|
# Get aete(s)
|
411
|
-
|
412
|
-
begin
|
413
|
-
aetes = AEM::Codecs.new.unpack(AE.get_app_terminology(app_path).coerce(KAE::TypeAEList))
|
414
|
-
rescue NotImplementedError # get_app_terminology is unavailable on 64-bit Leopard
|
415
|
-
aetes = Terminology.aetes_for_app(AEM::Application.by_path(app_path))
|
416
|
-
end
|
417
|
-
rescue AE::MacOSError => e
|
418
|
-
if e.to_i == -192 # aete resource not found
|
419
|
-
raise RuntimeError, "No terminology found."
|
420
|
-
else
|
421
|
-
raise
|
422
|
-
end
|
423
|
-
end
|
464
|
+
aetes = Terminology.aetes_for_app(Application.by_path(app_path))
|
424
465
|
aetes.delete_if { |aete| not(aete.is_a?(AE::AEDesc) and aete.type == KAE::TypeAETE) }
|
425
|
-
# Parse aete(s) into intermediate tables, suitable for use by Terminology#tables_for_module
|
426
466
|
tables = TerminologyParser.build_tables_for_aetes(aetes)
|
427
|
-
|
428
|
-
File.open(out_path, "w") do |f|
|
429
|
-
f.puts "module #{module_name}"
|
430
|
-
f.puts "\tVersion = 1.1"
|
431
|
-
f.puts "\tPath = #{app_path.inspect}"
|
432
|
-
f.puts
|
433
|
-
(["Classes", "Enumerators", "Properties", "Elements"].zip(tables[0,4])).each do |name, table|
|
434
|
-
f.puts "\t#{name} = ["
|
435
|
-
table.sort.each do |item|
|
436
|
-
f.puts "\t\t#{item.inspect},"
|
437
|
-
end
|
438
|
-
f.puts "\t]"
|
439
|
-
f.puts
|
440
|
-
end
|
441
|
-
f.puts "\tCommands = ["
|
442
|
-
tables[4].sort.each do |name, code, params|
|
443
|
-
f.puts "\t\t[#{name.inspect}, #{code.inspect}, ["
|
444
|
-
params.each do |item|
|
445
|
-
f.puts "\t\t\t#{item.inspect},"
|
446
|
-
end
|
447
|
-
f.puts "\t\t]],"
|
448
|
-
end
|
449
|
-
f.puts "\t]"
|
450
|
-
f.puts "end"
|
451
|
-
end
|
467
|
+
Terminology.dump_tables(tables, module_name, app_path, out_path)
|
452
468
|
end
|
469
|
+
|
453
470
|
end
|
454
471
|
|