rb-appscript 0.5.3 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
@@ -4,8 +4,6 @@
4
4
  # aem -- a mid-level object-oriented API for creating and sending Apple events
5
5
  # using raw AE codes; may be used directly or via high-level appscript wrapper
6
6
  #
7
- # Copyright (C) 2006-2009 HAS. Released under MIT License.
8
- #
9
7
 
10
8
  require "ae"
11
9
  require "kae"
@@ -39,7 +37,8 @@ module AEM
39
37
  AEProp = TypeWrappers::AEProp
40
38
  AEKey = TypeWrappers::AEKey
41
39
 
42
- CommandError = Send::CommandError
40
+ EventError = Send::EventError
41
+ CommandError = Send::EventError # deprecated class name; kept for backwards compatibility
43
42
 
44
43
  #######
45
44
  # Reference roots
@@ -63,7 +62,7 @@ module AEM
63
62
  #######
64
63
  # Application class
65
64
 
66
- class Application < AEMReference::Base
65
+ class Application < AEMReference::Query
67
66
  # Identifies an application and provides an #event method for constructing Apple events targetted at it.
68
67
 
69
68
  require "weakref"
@@ -4,8 +4,6 @@
4
4
  # appscript -- syntactically sugared wrapper around the mid-level aem API;
5
5
  # provides a high-level, easy-to-use API for creating and sending Apple events
6
6
  #
7
- # Copyright (C) 2006-2009 HAS. Released under MIT License.
8
- #
9
7
 
10
8
  require "_aem/mactypes"
11
9
 
@@ -118,7 +116,7 @@ module Appscript
118
116
  'aRef' => pack(ref),
119
117
  }).send)
120
118
  return nil
121
- rescue AEM::CommandError => e
119
+ rescue AEM::EventError => e
122
120
  return e
123
121
  end
124
122
  end
@@ -324,7 +322,8 @@ module Appscript
324
322
 
325
323
  def to_s
326
324
  s= @_call[0]
327
- @_call[1, @_call.length].each do |name, args| if name == :[]
325
+ @_call[1, @_call.length].each do |name, args|
326
+ if name == :[]
328
327
  if args.length == 1
329
328
  s += "[#{args[0].inspect}]"
330
329
  else
@@ -506,7 +505,7 @@ module Appscript
506
505
  begin
507
506
  return @AS_app_data.target.event(code, params, atts,
508
507
  KAE::KAutoGenerateReturnID, @AS_app_data).send(timeout, send_flags)
509
- rescue AEM::CommandError => e
508
+ rescue AEM::EventError => e
510
509
  if e.number == -1708 and code == 'ascrnoop'
511
510
  return # 'launch' events always return 'not handled' errors; just ignore these
512
511
  elsif [-600, -609].include?(e.number) and @AS_app_data.constructor == :by_path
@@ -535,7 +534,7 @@ module Appscript
535
534
  begin
536
535
  return @AS_app_data.target.event(code, params, atts,
537
536
  KAE::KAutoGenerateReturnID, @AS_app_data).send(timeout, send_flags)
538
- rescue AEM::CommandError => e
537
+ rescue AEM::EventError => e
539
538
  raise CommandError.new(self, name, args, e, @AS_app_data)
540
539
  end
541
540
  end
@@ -885,7 +884,7 @@ module Appscript
885
884
  def AS_new_reference(ref)
886
885
  if ref.is_a?(Appscript::GenericReference)
887
886
  return ref.AS_resolve(@AS_app_data)
888
- elsif ref.is_a?(AEMReference::Base)
887
+ elsif ref.is_a?(AEMReference::Query)
889
888
  return Reference.new(@AS_app_data, ref)
890
889
  elsif ref == nil
891
890
  return Reference.new(@AS_app_data, AEM.app)
@@ -913,7 +912,7 @@ module Appscript
913
912
  else
914
913
  begin
915
914
  @AS_app_data.target.event('ascrnoop').send # will send launch event to app if already running; else will error
916
- rescue AEM::CommandError => e
915
+ rescue AEM::EventError => e
917
916
  raise if e.to_i != -1708
918
917
  end
919
918
  end
@@ -1021,7 +1020,7 @@ module Appscript
1021
1020
  end
1022
1021
 
1023
1022
  def to_s
1024
- if @real_error.is_a?(AEM::CommandError)
1023
+ if @real_error.is_a?(AEM::EventError)
1025
1024
  err = "CommandError\n\t\tOSERROR: #{error_number}"
1026
1025
  err += "\n\t\tMESSAGE: #{error_message}" if error_message != ''
1027
1026
  [
@@ -1039,7 +1038,7 @@ module Appscript
1039
1038
  end
1040
1039
 
1041
1040
  def error_number
1042
- if @real_error.is_a?(AE::MacOSError) or @real_error.is_a?(AEM::CommandError)
1041
+ if @real_error.is_a?(AE::MacOSError) or @real_error.is_a?(AEM::EventError)
1043
1042
  return @real_error.to_i
1044
1043
  else
1045
1044
  return -2700
@@ -1053,19 +1052,19 @@ module Appscript
1053
1052
  end
1054
1053
 
1055
1054
  def offending_object
1056
- return nil if not @real_error.is_a?(AEM::CommandError)
1055
+ return nil if not @real_error.is_a?(AEM::EventError)
1057
1056
  desc = @real_error.raw[KAE::KOSAErrorOffendingObject]
1058
1057
  return desc ? @codecs.unpack(desc) : nil
1059
1058
  end
1060
1059
 
1061
1060
  def expected_type
1062
- return nil if not @real_error.is_a?(AEM::CommandError)
1061
+ return nil if not @real_error.is_a?(AEM::EventError)
1063
1062
  desc = @real_error.raw[KAE::KOSAErrorExpectedType]
1064
1063
  return desc ? @codecs.unpack(desc) : nil
1065
1064
  end
1066
1065
 
1067
1066
  def partial_result
1068
- return nil if not @real_error.is_a?(AEM::CommandError)
1067
+ return nil if not @real_error.is_a?(AEM::EventError)
1069
1068
  desc = @real_error.raw[KAE::KOSAErrorPartialResult]
1070
1069
  return desc ? @codecs.unpack(desc) : nil
1071
1070
  end
@@ -3,20 +3,411 @@
3
3
  #
4
4
  # osax -- invoke scripting addition (OSAX) commands from Ruby
5
5
  #
6
- # Copyright (C) 2006-2009 HAS. Released under MIT License.
7
- #
8
6
 
9
7
  require "appscript"
10
8
 
11
9
  module OSAX
10
+
12
11
 
13
12
  ######################################################################
14
13
  # PRIVATE
15
14
  ######################################################################
16
15
 
16
+ require 'rexml/document'
17
17
  require "ae"
18
18
  require "kae"
19
19
  require "aem"
20
+ require "_appscript/reservedkeywords" # names of all existing methods on ASReference::Application
21
+
22
+ StandardAdditionsEnums = [
23
+ ["stop", "\000\000\000\000"],
24
+ ["note", "\000\000\000\001"],
25
+ ["caution", "\000\000\000\002"]]
26
+
27
+ UTF8ToMacRoman = {
28
+ 0 => 0,
29
+ 1 => 1,
30
+ 2 => 2,
31
+ 3 => 3,
32
+ 4 => 4,
33
+ 5 => 5,
34
+ 6 => 6,
35
+ 7 => 7,
36
+ 8 => 8,
37
+ 9 => 9,
38
+ 10 => 10,
39
+ 11 => 11,
40
+ 12 => 12,
41
+ 13 => 13,
42
+ 14 => 14,
43
+ 15 => 15,
44
+ 16 => 16,
45
+ 17 => 17,
46
+ 18 => 18,
47
+ 19 => 19,
48
+ 20 => 20,
49
+ 21 => 21,
50
+ 22 => 22,
51
+ 23 => 23,
52
+ 24 => 24,
53
+ 25 => 25,
54
+ 26 => 26,
55
+ 27 => 27,
56
+ 28 => 28,
57
+ 29 => 29,
58
+ 30 => 30,
59
+ 31 => 31,
60
+ 32 => 32,
61
+ 33 => 33,
62
+ 34 => 34,
63
+ 35 => 35,
64
+ 36 => 36,
65
+ 37 => 37,
66
+ 38 => 38,
67
+ 39 => 39,
68
+ 40 => 40,
69
+ 41 => 41,
70
+ 42 => 42,
71
+ 43 => 43,
72
+ 44 => 44,
73
+ 45 => 45,
74
+ 46 => 46,
75
+ 47 => 47,
76
+ 48 => 48,
77
+ 49 => 49,
78
+ 50 => 50,
79
+ 51 => 51,
80
+ 52 => 52,
81
+ 53 => 53,
82
+ 54 => 54,
83
+ 55 => 55,
84
+ 56 => 56,
85
+ 57 => 57,
86
+ 58 => 58,
87
+ 59 => 59,
88
+ 60 => 60,
89
+ 61 => 61,
90
+ 62 => 62,
91
+ 63 => 63,
92
+ 64 => 64,
93
+ 65 => 65,
94
+ 66 => 66,
95
+ 67 => 67,
96
+ 68 => 68,
97
+ 69 => 69,
98
+ 70 => 70,
99
+ 71 => 71,
100
+ 72 => 72,
101
+ 73 => 73,
102
+ 74 => 74,
103
+ 75 => 75,
104
+ 76 => 76,
105
+ 77 => 77,
106
+ 78 => 78,
107
+ 79 => 79,
108
+ 80 => 80,
109
+ 81 => 81,
110
+ 82 => 82,
111
+ 83 => 83,
112
+ 84 => 84,
113
+ 85 => 85,
114
+ 86 => 86,
115
+ 87 => 87,
116
+ 88 => 88,
117
+ 89 => 89,
118
+ 90 => 90,
119
+ 91 => 91,
120
+ 92 => 92,
121
+ 93 => 93,
122
+ 94 => 94,
123
+ 95 => 95,
124
+ 96 => 96,
125
+ 97 => 97,
126
+ 98 => 98,
127
+ 99 => 99,
128
+ 100 => 100,
129
+ 101 => 101,
130
+ 102 => 102,
131
+ 103 => 103,
132
+ 104 => 104,
133
+ 105 => 105,
134
+ 106 => 106,
135
+ 107 => 107,
136
+ 108 => 108,
137
+ 109 => 109,
138
+ 110 => 110,
139
+ 111 => 111,
140
+ 112 => 112,
141
+ 113 => 113,
142
+ 114 => 114,
143
+ 115 => 115,
144
+ 116 => 116,
145
+ 117 => 117,
146
+ 118 => 118,
147
+ 119 => 119,
148
+ 120 => 120,
149
+ 121 => 121,
150
+ 122 => 122,
151
+ 123 => 123,
152
+ 124 => 124,
153
+ 125 => 125,
154
+ 126 => 126,
155
+ 127 => 127,
156
+ 196 => 128,
157
+ 197 => 129,
158
+ 199 => 130,
159
+ 201 => 131,
160
+ 209 => 132,
161
+ 214 => 133,
162
+ 220 => 134,
163
+ 225 => 135,
164
+ 224 => 136,
165
+ 226 => 137,
166
+ 228 => 138,
167
+ 227 => 139,
168
+ 229 => 140,
169
+ 231 => 141,
170
+ 233 => 142,
171
+ 232 => 143,
172
+ 234 => 144,
173
+ 235 => 145,
174
+ 237 => 146,
175
+ 236 => 147,
176
+ 238 => 148,
177
+ 239 => 149,
178
+ 241 => 150,
179
+ 243 => 151,
180
+ 242 => 152,
181
+ 244 => 153,
182
+ 246 => 154,
183
+ 245 => 155,
184
+ 250 => 156,
185
+ 249 => 157,
186
+ 251 => 158,
187
+ 252 => 159,
188
+ 8224 => 160,
189
+ 176 => 161,
190
+ 162 => 162,
191
+ 163 => 163,
192
+ 167 => 164,
193
+ 8226 => 165,
194
+ 182 => 166,
195
+ 223 => 167,
196
+ 174 => 168,
197
+ 169 => 169,
198
+ 8482 => 170,
199
+ 180 => 171,
200
+ 168 => 172,
201
+ 8800 => 173,
202
+ 198 => 174,
203
+ 216 => 175,
204
+ 8734 => 176,
205
+ 177 => 177,
206
+ 8804 => 178,
207
+ 8805 => 179,
208
+ 165 => 180,
209
+ 181 => 181,
210
+ 8706 => 182,
211
+ 8721 => 183,
212
+ 8719 => 184,
213
+ 960 => 185,
214
+ 8747 => 186,
215
+ 170 => 187,
216
+ 186 => 188,
217
+ 937 => 189,
218
+ 230 => 190,
219
+ 248 => 191,
220
+ 191 => 192,
221
+ 161 => 193,
222
+ 172 => 194,
223
+ 8730 => 195,
224
+ 402 => 196,
225
+ 8776 => 197,
226
+ 8710 => 198,
227
+ 171 => 199,
228
+ 187 => 200,
229
+ 8230 => 201,
230
+ 160 => 202,
231
+ 192 => 203,
232
+ 195 => 204,
233
+ 213 => 205,
234
+ 338 => 206,
235
+ 339 => 207,
236
+ 8211 => 208,
237
+ 8212 => 209,
238
+ 8220 => 210,
239
+ 8221 => 211,
240
+ 8216 => 212,
241
+ 8217 => 213,
242
+ 247 => 214,
243
+ 9674 => 215,
244
+ 255 => 216,
245
+ 376 => 217,
246
+ 8260 => 218,
247
+ 8364 => 219,
248
+ 8249 => 220,
249
+ 8250 => 221,
250
+ 64257 => 222,
251
+ 64258 => 223,
252
+ 8225 => 224,
253
+ 183 => 225,
254
+ 8218 => 226,
255
+ 8222 => 227,
256
+ 8240 => 228,
257
+ 194 => 229,
258
+ 202 => 230,
259
+ 193 => 231,
260
+ 203 => 232,
261
+ 200 => 233,
262
+ 205 => 234,
263
+ 206 => 235,
264
+ 207 => 236,
265
+ 204 => 237,
266
+ 211 => 238,
267
+ 212 => 239,
268
+ 63743 => 240,
269
+ 210 => 241,
270
+ 218 => 242,
271
+ 219 => 243,
272
+ 217 => 244,
273
+ 305 => 245,
274
+ 710 => 246,
275
+ 732 => 247,
276
+ 175 => 248,
277
+ 728 => 249,
278
+ 729 => 250,
279
+ 730 => 251,
280
+ 184 => 252,
281
+ 733 => 253,
282
+ 731 => 254,
283
+ 711 => 255}
284
+
285
+ class SdefParser
286
+ @@_name_cache = {}
287
+ LegalFirst = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_'
288
+ LegalRest = LegalFirst + '0123456789'
289
+ @@_reserved_keywords = {} # ersatz set
290
+ ReservedKeywords.each { |name| @@_reserved_keywords[name] = nil }
291
+
292
+ attr_reader :properties, :elements, :classes, :enumerators
293
+
294
+ def commands
295
+ return @commands.values
296
+ end
297
+
298
+ def initialize
299
+ # terminology tables; order is significant where synonym definitions occur
300
+ @commands = {}
301
+ @properties = []
302
+ @elements = []
303
+ @classes = []
304
+ @enumerators = []
305
+ end
306
+
307
+ def _name(s)
308
+ # Read a MacRoman-encoded Pascal keyword string.
309
+ if not @@_name_cache.has_key?(s)
310
+ legal = LegalFirst
311
+ res = ''
312
+ s.split(//).each do |c|
313
+ if legal[c]
314
+ res += c
315
+ else
316
+ case c
317
+ when ' ', '-', '/'
318
+ res += '_'
319
+ when '&'
320
+ res += 'and'
321
+ else
322
+ if res == ''
323
+ res = '_'
324
+ end
325
+ res += "0x#{c.unpack('HXh')}"
326
+ end
327
+ end
328
+ legal = LegalRest
329
+ end
330
+ if res[0, 3] == 'AS_' or @@_reserved_keywords.has_key?(res) or res[0, 1] == '_'
331
+ res += '_'
332
+ end
333
+ @@_name_cache[s] = res
334
+ end
335
+ return @@_name_cache[s]
336
+ end
337
+
338
+ def _code(s)
339
+ return s.unpack('U*').collect do |c| # unpack UTF8-encoded byte string
340
+ OSAX::UTF8ToMacRoman.fetch(c)
341
+ end .pack('C*') # pack as MacRoman-encoded byte string (four- or eight-char code)
342
+ end
343
+
344
+ def _addnamecode(node, collection)
345
+ name = _name(node.attributes['name'])
346
+ code = _code(node.attributes['code'])
347
+ if name != '' and code.size == 4 and not collection.include?([name, code])
348
+ collection.push([name, code])
349
+ end
350
+ end
351
+
352
+ def _addcommand(node)
353
+ name = _name(node.attributes['name'])
354
+ code = _code(node.attributes['code'])
355
+ parameters = []
356
+ # Note: overlapping command definitions (e.g. 'path to') should be processed as follows:
357
+ # - If their names and codes are the same, only the last definition is used; other definitions are ignored and will not compile.
358
+ # - If their names are the same but their codes are different, only the first definition is used; other definitions are ignored and will not compile.
359
+ if name != '' and code.size == 8 and (not @commands.has_key?(name) or @commands[name][1] == code)
360
+ @commands[name] = [name, code, parameters]
361
+ node.each_element('parameter') do |pnode|
362
+ _addnamecode(pnode, parameters)
363
+ end
364
+ end
365
+ end
366
+
367
+ def parse(xml)
368
+ # Extract name-code mappings from an sdef.
369
+ #
370
+ # xml : String -- sdef data
371
+ xml = REXML::Document.new(xml)
372
+ xml.root.each_element('suite/*') do |node|
373
+ begin
374
+ if ['command', 'event'].include?(node.name)
375
+ _addcommand(node)
376
+ elsif ['class', 'record-type', 'value-type'].include?(node.name)
377
+ _addnamecode(node, @classes)
378
+ node.each_element('property') do |prop|
379
+ _addnamecode(prop, @properties)
380
+ end
381
+ if node.name == 'class' # elements
382
+ name = node.attributes['plural']
383
+ if name == nil
384
+ name = node.attributes['name']
385
+ name = "#{name}s" if name != nil
386
+ end
387
+ name = _name(name)
388
+ code = _code(node.attributes['code'])
389
+ if name != '' and code.size == 4
390
+ @elements.push([name, code])
391
+ end
392
+ end
393
+ elsif node.name == 'enumeration'
394
+ node.each_element('enumerator') do |enum|
395
+ _addnamecode(enum, @enumerators)
396
+ end
397
+ end
398
+ rescue # ignore problem definitions
399
+ end
400
+ end
401
+ end
402
+
403
+ def parse_file(path)
404
+ # Extract name-code mappings from an sdef.
405
+ #
406
+ # path : String -- path to .sdef file
407
+ parse(AE.copy_scripting_definition(path))
408
+ end
409
+
410
+ end
20
411
 
21
412
  #######
22
413
  # cache; stores osax paths and previously parsed terminology (if any) by osax name
@@ -37,7 +428,7 @@ module OSAX
37
428
  super
38
429
  begin
39
430
  @target.event('ascrgdut').send(60 * 60) # make sure target application has loaded event handlers for all installed OSAXen
40
- rescue AEM::CommandError => e
431
+ rescue AEM::EventError => e
41
432
  if e.number != -1708 # ignore 'event not handled' error
42
433
  raise
43
434
  end
@@ -147,13 +538,12 @@ module OSAX
147
538
  raise ArgumentError, "Scripting addition not found: #{name.inspect}"
148
539
  end
149
540
  if not terminology_tables
150
- begin
151
- aetes_desc = AE.get_app_terminology(path) # will raise NotImplementedError in 64-bit processes
152
- rescue NotImplementedError
153
- raise RuntimeError, "OSAX::ScriptingAddition can't dynamically retrieve scripting addition terminology within a 64-bit process."
541
+ sp = OSAX::SdefParser.new
542
+ sp.parse_file(path)
543
+ if osax_name == 'standardadditions'
544
+ OSAX::StandardAdditionsEnums.each { |o| sp.enumerators.push(o)}
154
545
  end
155
- aetes = DefaultCodecs.unpack(aetes_desc.coerce(KAE::TypeAEList))
156
- terminology_tables = Terminology.tables_for_aetes(aetes)
546
+ terminology_tables = Terminology.tables_for_parsed_sdef(sp)
157
547
  OSAXCache[osax_name][1] = terminology_tables
158
548
  end
159
549
  @_terms = terminology_tables
@@ -228,5 +618,42 @@ module OSAX
228
618
  return ScriptingAddition.new(@_osax_name, OSAXData.new(:current, nil, @_terms))
229
619
  end
230
620
  end
621
+
622
+ #######
231
623
 
624
+ def OSAX.dump(osax_name, module_name, out_path)
625
+ # Export scripting addition terminology tables as a Ruby module
626
+ # osaxname : string -- name of installed scripting addition
627
+ # module_name : string -- name of generated module (must be a valid Ruby constant)
628
+ # out_path : string -- module file to write
629
+ #
630
+ # Generates a Ruby module containing a scripting addition's basic terminology
631
+ # (names and codes).
632
+ #
633
+ # Call the #dump method to dump faulty sdefs to Ruby module, e.g.:
634
+ #
635
+ # dump('MyOSAX', 'MyOSAXGlue', '/path/to/site-packages/myosaxglue.py')
636
+ #
637
+ # Patch any errors by hand, then import the patched module into your script
638
+ # and pass it to OSAX.osax via its 'terms' argument, e.g.:
639
+ #
640
+ # require 'osax'
641
+ # require 'MyOSAXGlue'
642
+ #
643
+ # myapp = OSAX.osax('MyOSAX', terms => MyOSAXGlue)
644
+ #
645
+ OSAX._init_caches if OSAXNames == []
646
+ original_name = osax_name
647
+ osax_name = osax_name.downcase
648
+ m = /^(.+).osax$/.match(osax_name)
649
+ osax_name = m[1] if m != nil
650
+ osax_path, terms = OSAXCache.fetch(osax_name) do
651
+ raise ArgumentError, "Scripting addition not found: #{original_name.inspect}"
652
+ end
653
+ sp = OSAX::SdefParser.new
654
+ sp.parsefile(osax_path)
655
+ Terminology.dump_tables([sp.classes, sp.enumerators, sp.properties, sp.elements, sp.commands],
656
+ module_name, osax_path, out_path)
657
+ end
658
+
232
659
  end