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
@@ -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