rb-scpt 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (94) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGES +497 -0
  3. data/doc/aem-manual/01_introduction.html +60 -0
  4. data/doc/aem-manual/02_apioverview.html +107 -0
  5. data/doc/aem-manual/03_packingandunpackingdata.html +135 -0
  6. data/doc/aem-manual/04_references.html +409 -0
  7. data/doc/aem-manual/05_targetingapplications.html +164 -0
  8. data/doc/aem-manual/06_buildingandsendingevents.html +229 -0
  9. data/doc/aem-manual/07_findapp.html +63 -0
  10. data/doc/aem-manual/08_examples.html +94 -0
  11. data/doc/aem-manual/aemreferenceinheritance.gif +0 -0
  12. data/doc/aem-manual/index.html +56 -0
  13. data/doc/appscript-manual/01_introduction.html +94 -0
  14. data/doc/appscript-manual/02_aboutappscripting.html +247 -0
  15. data/doc/appscript-manual/03_quicktutorial.html +167 -0
  16. data/doc/appscript-manual/04_gettinghelp.html +188 -0
  17. data/doc/appscript-manual/05_keywordconversion.html +106 -0
  18. data/doc/appscript-manual/06_classesandenums.html +192 -0
  19. data/doc/appscript-manual/07_applicationobjects.html +211 -0
  20. data/doc/appscript-manual/08_realvsgenericreferences.html +96 -0
  21. data/doc/appscript-manual/09_referenceforms.html +241 -0
  22. data/doc/appscript-manual/10_referenceexamples.html +154 -0
  23. data/doc/appscript-manual/11_applicationcommands.html +245 -0
  24. data/doc/appscript-manual/12_commandexamples.html +138 -0
  25. data/doc/appscript-manual/13_performanceissues.html +142 -0
  26. data/doc/appscript-manual/14_notes.html +80 -0
  27. data/doc/appscript-manual/application_architecture.gif +0 -0
  28. data/doc/appscript-manual/application_architecture2.gif +0 -0
  29. data/doc/appscript-manual/finder_to_textedit_event.gif +0 -0
  30. data/doc/appscript-manual/index.html +62 -0
  31. data/doc/appscript-manual/relationships_example.gif +0 -0
  32. data/doc/appscript-manual/ruby_to_itunes_event.gif +0 -0
  33. data/doc/full.css +106 -0
  34. data/doc/index.html +45 -0
  35. data/doc/mactypes-manual/01_introduction.html +54 -0
  36. data/doc/mactypes-manual/02_aliasclass.html +124 -0
  37. data/doc/mactypes-manual/03_fileurlclass.html +126 -0
  38. data/doc/mactypes-manual/04_unitsclass.html +100 -0
  39. data/doc/mactypes-manual/index.html +53 -0
  40. data/doc/osax-manual/01_introduction.html +67 -0
  41. data/doc/osax-manual/02_interface.html +147 -0
  42. data/doc/osax-manual/03_examples.html +73 -0
  43. data/doc/osax-manual/04_notes.html +61 -0
  44. data/doc/osax-manual/index.html +53 -0
  45. data/doc/rb-appscript-logo.png +0 -0
  46. data/extconf.rb +65 -0
  47. data/rb-scpt.gemspec +14 -0
  48. data/sample/AB_export_vcard.rb +31 -0
  49. data/sample/AB_list_people_with_emails.rb +13 -0
  50. data/sample/Add_iCal_event.rb +21 -0
  51. data/sample/Create_daily_iCal_todos.rb +75 -0
  52. data/sample/Export_Address_Book_phone_numbers.rb +59 -0
  53. data/sample/Hello_world.rb +21 -0
  54. data/sample/List_iTunes_playlist_names.rb +11 -0
  55. data/sample/Make_Mail_message.rb +33 -0
  56. data/sample/Open_file_in_TextEdit.rb +13 -0
  57. data/sample/Organize_Mail_messages.rb +61 -0
  58. data/sample/Print_folder_tree.rb +16 -0
  59. data/sample/Select_all_HTML_files.rb +14 -0
  60. data/sample/Set_iChat_status.rb +24 -0
  61. data/sample/Simple_Finder_GUI_Scripting.rb +18 -0
  62. data/sample/Stagger_Finder_windows.rb +25 -0
  63. data/sample/TextEdit_demo.rb +130 -0
  64. data/sample/iTunes_top40_to_html.rb +71 -0
  65. data/src/SendThreadSafe.c +380 -0
  66. data/src/SendThreadSafe.h +139 -0
  67. data/src/lib/_aem/aemreference.rb +1022 -0
  68. data/src/lib/_aem/codecs.rb +662 -0
  69. data/src/lib/_aem/connect.rb +205 -0
  70. data/src/lib/_aem/encodingsupport.rb +77 -0
  71. data/src/lib/_aem/findapp.rb +85 -0
  72. data/src/lib/_aem/mactypes.rb +251 -0
  73. data/src/lib/_aem/send.rb +279 -0
  74. data/src/lib/_aem/typewrappers.rb +59 -0
  75. data/src/lib/_appscript/defaultterminology.rb +277 -0
  76. data/src/lib/_appscript/referencerenderer.rb +245 -0
  77. data/src/lib/_appscript/reservedkeywords.rb +116 -0
  78. data/src/lib/_appscript/safeobject.rb +249 -0
  79. data/src/lib/_appscript/terminology.rb +471 -0
  80. data/src/lib/aem.rb +253 -0
  81. data/src/lib/appscript.rb +1075 -0
  82. data/src/lib/kae.rb +1489 -0
  83. data/src/lib/osax.rb +659 -0
  84. data/src/rbae.c +979 -0
  85. data/test/README +3 -0
  86. data/test/test_aemreference.rb +118 -0
  87. data/test/test_appscriptcommands.rb +152 -0
  88. data/test/test_appscriptreference.rb +106 -0
  89. data/test/test_codecs.rb +186 -0
  90. data/test/test_findapp.rb +26 -0
  91. data/test/test_mactypes.rb +79 -0
  92. data/test/test_osax.rb +54 -0
  93. data/test/testall.sh +10 -0
  94. metadata +145 -0
@@ -0,0 +1,659 @@
1
+ #
2
+ # rb-appscript
3
+ #
4
+ # osax -- invoke scripting addition (OSAX) commands from Ruby
5
+ #
6
+
7
+ require "appscript"
8
+
9
+ module OSAX
10
+
11
+
12
+ ######################################################################
13
+ # PRIVATE
14
+ ######################################################################
15
+
16
+ require 'rexml/document'
17
+ require "ae"
18
+ require "kae"
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
411
+
412
+ #######
413
+ # cache; stores osax paths and previously parsed terminology (if any) by osax name
414
+
415
+ OSAXCache = {}
416
+ OSAXNames = []
417
+
418
+ #######
419
+ # modified AppData class
420
+
421
+ class OSAXData < Appscript::AppData
422
+
423
+ def initialize(constructor, identifier, terms)
424
+ super(AEM::Application, constructor, identifier, terms)
425
+ end
426
+
427
+ def connect
428
+ super
429
+ begin
430
+ @target.event('ascrgdut').send(60 * 60) # make sure target application has loaded event handlers for all installed OSAXen
431
+ rescue AEM::EventError => e
432
+ if e.number != -1708 # ignore 'event not handled' error
433
+ raise
434
+ end
435
+ end
436
+ end
437
+
438
+ end
439
+
440
+ @_standard_additions = nil
441
+
442
+ def OSAX._init_caches
443
+ se = AEM::Application.by_path(FindApp.by_id('com.apple.systemevents'))
444
+ ['flds', 'fldl', 'fldu'].each do |domain_code|
445
+ osaxen = AEM.app.property(domain_code).property('$scr').elements('file').by_filter(
446
+ AEM.its.property('asty').eq('osax').or(AEM.its.property('extn').eq('osax')))
447
+ if se.event('coredoex', {'----' => osaxen.property('pnam')}).send # domain has ScriptingAdditions folder
448
+ names = se.event('coregetd', {'----' => osaxen.property('pnam')}).send
449
+ paths = se.event('coregetd', {'----' => osaxen.property('posx')}).send
450
+ names.zip(paths).each do |name, path|
451
+ name = name.sub(/(?i)\.osax$/, '') # remove name extension, if any
452
+ OSAXNames.push(name)
453
+ OSAXCache[name.downcase] = [path, nil]
454
+ end
455
+ end
456
+ end
457
+ OSAXNames.sort!.uniq!
458
+ end
459
+
460
+ ######################################################################
461
+ # PUBLIC
462
+ ######################################################################
463
+
464
+ def OSAX.scripting_additions
465
+ # list names of all currently installed scripting additions
466
+ OSAX._init_caches if OSAXNames == []
467
+ return OSAXNames.clone
468
+ end
469
+
470
+ def OSAX.osax(name=nil, app_name=nil)
471
+ # Convenience method for creating a new ScriptingAddition instance.
472
+ # name : String | nil -- scripting addition's name; nil = 'StandardAdditions'
473
+ # app_name : String | nil -- target application's name/path, or nil for current application
474
+ # Result : ScriptingAddition
475
+ #
476
+ # If both arguments are nil, a ScriptingAddition object for StandardAdditions is created
477
+ # and returned. This object is cached for efficiency and returned in subsequent calls;
478
+ # thus clients can conveniently write (e.g):
479
+ #
480
+ # osax.some_command
481
+ # osax.another_command
482
+ #
483
+ # instead of:
484
+ #
485
+ # sa = osax
486
+ # sa.some_command
487
+ # sa.another_command
488
+ #
489
+ # without the additional overhead of creating a new ScriptingAddition object each time.
490
+ #
491
+ if name == nil and app_name == nil
492
+ if @_standard_additions == nil
493
+ @_standard_additions = ScriptingAddition.new('StandardAdditions')
494
+ end
495
+ addition = @_standard_additions
496
+ else
497
+ if name == nil
498
+ name = 'StandardAdditions'
499
+ end
500
+ addition = ScriptingAddition.new(name)
501
+ if app_name
502
+ addition = addition.by_name(app_name)
503
+ end
504
+ end
505
+ return addition
506
+ end
507
+
508
+ # allow methods to be included via 'include OSAX'
509
+
510
+ def scripting_additions
511
+ return OSAX.scripting_additions
512
+ end
513
+
514
+ def osax(*args)
515
+ return OSAX.osax(*args)
516
+ end
517
+
518
+ #######
519
+
520
+ class ScriptingAddition < Appscript::Reference
521
+ # Represents a single scripting addition.
522
+
523
+ def initialize(name, terms=nil)
524
+ # name: string -- a scripting addition's name, e.g. "StandardAdditions";
525
+ # basically its filename minus the '.osax' suffix
526
+ #
527
+ # terms : module or nil -- an optional terminology glue module,
528
+ # as exported by Terminology.dump; if given, ScriptingAddition
529
+ # will use this instead of retrieving the terminology dynamically
530
+ #
531
+ # Note that name is case-insensitive and an '.osax' suffix is ignored if given.
532
+ @_osax_name = name
533
+ if not terms
534
+ osax_name = name.downcase.sub(/(?i)\.osax$/, '')
535
+ OSAX._init_caches if OSAXCache == {}
536
+ path, terminology_tables = OSAXCache[osax_name]
537
+ if not path
538
+ raise ArgumentError, "Scripting addition not found: #{name.inspect}"
539
+ end
540
+ if not terminology_tables
541
+ sp = OSAX::SdefParser.new
542
+ sp.parse_file(path)
543
+ if osax_name == 'standardadditions'
544
+ OSAX::StandardAdditionsEnums.each { |o| sp.enumerators.push(o)}
545
+ end
546
+ terminology_tables = Terminology.tables_for_parsed_sdef(sp)
547
+ OSAXCache[osax_name][1] = terminology_tables
548
+ end
549
+ @_terms = terminology_tables
550
+ terms = OSAXData.new(:current, nil, @_terms)
551
+ elsif not terms.is_a?(OSAX::OSAXData) # assume it's a glue module
552
+ terminology_tables = Terminology.tables_for_module(terms)
553
+ @_terms = terminology_tables
554
+ terms = OSAXData.new(:current, nil, @_terms)
555
+ end
556
+ super(terms, AEM.app)
557
+ end
558
+
559
+ def to_s
560
+ return "#<OSAX::ScriptingAddition name=#{@_osax_name.inspect} target=#{@AS_app_data.target.inspect}>"
561
+ end
562
+
563
+ alias_method :inspect, :to_s
564
+
565
+ ##
566
+
567
+ def method_missing(name, *args)
568
+ begin
569
+ super
570
+ rescue Appscript::CommandError => e
571
+ if e.to_i == -1713 # 'No user interaction allowed' error (e.g. user tried to send a 'display dialog' command to a non-GUI ruby process), so convert the target process to a full GUI process and try again
572
+ AE.transform_process_to_foreground_application
573
+ activate
574
+ super
575
+ else
576
+ raise
577
+ end
578
+ end
579
+ end
580
+
581
+ # A client-created scripting addition is automatically targetted at the current application.
582
+ # Clients can specify another application as target by calling one of the following methods:
583
+
584
+ def by_name(name)
585
+ # name : string -- name or full path to application
586
+ return ScriptingAddition.new(@_osax_name,
587
+ OSAXData.new(:by_path, FindApp.by_name(name), @_terms))
588
+ end
589
+
590
+ def by_id(id)
591
+ # id : string -- bundle id of application
592
+ return ScriptingAddition.new(@_osax_name,
593
+ OSAXData.new(:by_path, FindApp.by_id(id), @_terms))
594
+ end
595
+
596
+ def by_creator(creator)
597
+ # creator : string -- four-character creator code of application
598
+ return ScriptingAddition.new(@_osax_name,
599
+ OSAXData.new(:by_path, FindApp.by_creator(creator), @_terms))
600
+ end
601
+
602
+ def by_pid(pid)
603
+ # pid : integer -- Unix process id
604
+ return ScriptingAddition.new(@_osax_name, OSAXData.new(:by_pid, pid, @_terms))
605
+ end
606
+
607
+ def by_url(url)
608
+ # url : string -- eppc URL of application
609
+ return ScriptingAddition.new(@_osax_name, OSAXData.new(:by_url, url, @_terms))
610
+ end
611
+
612
+ def by_aem_app(aem_app)
613
+ # aem_app : AEM::Application -- an AEM::Application instance
614
+ return ScriptingAddition.new(@_osax_name, OSAXData.new(:by_aem_app, aem_app, @_terms))
615
+ end
616
+
617
+ def current
618
+ return ScriptingAddition.new(@_osax_name, OSAXData.new(:current, nil, @_terms))
619
+ end
620
+ end
621
+
622
+ #######
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
+
659
+ end