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.
Files changed (79) hide show
  1. data/CHANGES +28 -0
  2. data/README +51 -31
  3. data/doc/aem-manual/01_introduction.html +0 -2
  4. data/doc/aem-manual/02_apioverview.html +13 -9
  5. data/doc/aem-manual/03_packingandunpackingdata.html +41 -9
  6. data/doc/aem-manual/04_references.html +42 -40
  7. data/doc/aem-manual/{05_targettingapplications.html → 05_targetingapplications.html} +4 -6
  8. data/doc/aem-manual/06_buildingandsendingevents.html +40 -12
  9. data/doc/aem-manual/07_findapp.html +0 -2
  10. data/doc/aem-manual/08_examples.html +0 -2
  11. data/doc/aem-manual/aemreferenceinheritance.gif +0 -0
  12. data/doc/aem-manual/index.html +1 -3
  13. data/doc/appscript-manual/01_introduction.html +0 -2
  14. data/doc/appscript-manual/02_aboutappscripting.html +4 -6
  15. data/doc/appscript-manual/03_quicktutorial.html +1 -3
  16. data/doc/appscript-manual/04_gettinghelp.html +20 -7
  17. data/doc/appscript-manual/05_keywordconversion.html +5 -3
  18. data/doc/appscript-manual/06_classesandenums.html +32 -8
  19. data/doc/appscript-manual/07_applicationobjects.html +30 -41
  20. data/doc/appscript-manual/08_realvsgenericreferences.html +0 -2
  21. data/doc/appscript-manual/09_referenceforms.html +0 -2
  22. data/doc/appscript-manual/10_referenceexamples.html +1 -3
  23. data/doc/appscript-manual/11_applicationcommands.html +29 -2
  24. data/doc/appscript-manual/12_commandexamples.html +0 -2
  25. data/doc/appscript-manual/13_performanceissues.html +0 -2
  26. data/doc/appscript-manual/14_notes.html +0 -19
  27. data/doc/appscript-manual/index.html +0 -2
  28. data/doc/index.html +1 -4
  29. data/doc/mactypes-manual/01_introduction.html +0 -2
  30. data/doc/mactypes-manual/02_aliasclass.html +0 -10
  31. data/doc/mactypes-manual/03_fileurlclass.html +1 -11
  32. data/doc/mactypes-manual/04_unitsclass.html +0 -2
  33. data/doc/mactypes-manual/index.html +0 -2
  34. data/doc/osax-manual/01_introduction.html +0 -2
  35. data/doc/osax-manual/02_interface.html +0 -2
  36. data/doc/osax-manual/03_examples.html +0 -2
  37. data/doc/osax-manual/04_notes.html +6 -25
  38. data/doc/osax-manual/index.html +0 -2
  39. data/rb-appscript.gemspec +2 -3
  40. data/sample/AB_export_vcard.rb +0 -0
  41. data/sample/AB_list_people_with_emails.rb +0 -0
  42. data/sample/Create_daily_iCal_todos.rb +0 -0
  43. data/sample/Export_Address_Book_phone_numbers.rb +0 -0
  44. data/sample/Hello_world.rb +0 -0
  45. data/sample/List_iTunes_playlist_names.rb +0 -0
  46. data/sample/Open_file_in_TextEdit.rb +0 -0
  47. data/sample/Organize_Mail_messages.rb +0 -0
  48. data/sample/TextEdit_demo.rb +0 -0
  49. data/sample/iTunes_top40_to_html.rb +0 -0
  50. data/src/SendThreadSafe.c +0 -0
  51. data/src/SendThreadSafe.h +0 -0
  52. data/src/lib/_aem/aemreference.rb +5 -7
  53. data/src/lib/_aem/codecs.rb +47 -24
  54. data/src/lib/_aem/connect.rb +29 -8
  55. data/src/lib/_aem/encodingsupport.rb +77 -0
  56. data/src/lib/_aem/findapp.rb +0 -2
  57. data/src/lib/_aem/mactypes.rb +0 -2
  58. data/src/lib/_aem/send.rb +6 -8
  59. data/src/lib/_aem/typewrappers.rb +0 -2
  60. data/src/lib/_appscript/defaultterminology.rb +0 -2
  61. data/src/lib/_appscript/referencerenderer.rb +1 -3
  62. data/src/lib/_appscript/reservedkeywords.rb +0 -2
  63. data/src/lib/_appscript/safeobject.rb +58 -9
  64. data/src/lib/_appscript/terminology.rb +63 -46
  65. data/src/lib/aem.rb +3 -4
  66. data/src/lib/appscript.rb +12 -13
  67. data/src/lib/osax.rb +436 -9
  68. data/src/rbae.c +126 -103
  69. data/test/test_aemreference.rb +0 -0
  70. data/test/test_appscriptcommands.rb +15 -1
  71. data/test/test_appscriptreference.rb +0 -0
  72. data/test/test_codecs.rb +10 -4
  73. data/test/test_findapp.rb +0 -0
  74. data/test/test_mactypes.rb +0 -0
  75. data/test/test_osax.rb +0 -0
  76. data/test/testall.sh +0 -0
  77. metadata +24 -24
  78. data/LICENSE +0 -70
  79. data/TODO +0 -19
@@ -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
- LaunchContinue = 0x4000
18
- LaunchNoFileFlags = 0x0800
19
- LaunchDontSwitch = 0x0200
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
- LaunchContinue + LaunchNoFileFlags + LaunchDontSwitch)
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::CommandError => err
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
@@ -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.
@@ -3,8 +3,6 @@
3
3
  #
4
4
  # mactypes -- Ruby classes representing Alias, FileURL and unit type AEDescs
5
5
  #
6
- # Copyright (C) 2006-2009 HAS. Released under MIT License.
7
- #
8
6
 
9
7
  module MacTypes
10
8
  # Defines wrapper classes for Mac OS datatypes that don't have a suitable Ruby equivalent.
@@ -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 CommandError class, which contains error information for a failed event.
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 CommandError.new(err.to_i)
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 CommandError.new(e_num, event_result)
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 CommandError < RuntimeError
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 "CommandError\n\t\tOSERROR: #{number}\n\t\tMESSAGE: #{message}"
256
+ return "EventError\n\t\tOSERROR: #{number}\n\t\tMESSAGE: #{message}"
259
257
  else
260
- return "CommandError\n\t\tOSERROR: #{number}"
258
+ return "EventError\n\t\tOSERROR: #{number}"
261
259
  end
262
260
  end
263
261
 
@@ -3,8 +3,6 @@
3
3
  #
4
4
  # typewrappers -- Ruby classes representing type, enumerator, property and keyword AEDescs
5
5
  #
6
- # Copyright (C) 2006-2009 HAS. Released under MIT License.
7
- #
8
6
 
9
7
  module TypeWrappers
10
8
 
@@ -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::Base)
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
- # Ruby License
64
- #
65
- # This module is free software. You may use, modify, and/or redistribute this
66
- # software under the same terms as Ruby.
67
- #
68
- # This program is distributed in the hope that it will be useful, but WITHOUT
69
- # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
70
- # FOR A PARTICULAR PURPOSE.
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::CommandError => e
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
- begin
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
- # Write module
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