Class: OSAX::SdefParser

Inherits:
Object
  • Object
show all
Defined in:
lib/osax.rb

Constant Summary collapse

LegalFirst =
'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_'
LegalRest =
LegalFirst + '0123456789'
@@_name_cache =
{}
@@_reserved_keywords =

ersatz set

{}

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeSdefParser

Returns a new instance of SdefParser.



298
299
300
301
302
303
304
305
# File 'lib/osax.rb', line 298

def initialize
  # terminology tables; order is significant where synonym definitions occur
  @commands = {}
  @properties = []
  @elements = []
  @classes = []
  @enumerators = []
end

Instance Attribute Details

#classesObject (readonly)

Returns the value of attribute classes.



292
293
294
# File 'lib/osax.rb', line 292

def classes
  @classes
end

#elementsObject (readonly)

Returns the value of attribute elements.



292
293
294
# File 'lib/osax.rb', line 292

def elements
  @elements
end

#enumeratorsObject (readonly)

Returns the value of attribute enumerators.



292
293
294
# File 'lib/osax.rb', line 292

def enumerators
  @enumerators
end

#propertiesObject (readonly)

Returns the value of attribute properties.



292
293
294
# File 'lib/osax.rb', line 292

def properties
  @properties
end

Instance Method Details

#_addcommand(node) ⇒ Object



352
353
354
355
356
357
358
359
360
361
362
363
364
365
# File 'lib/osax.rb', line 352

def _addcommand(node)
  name = _name(node.attributes['name'])
  code = _code(node.attributes['code'])
  parameters = []
  # Note: overlapping command definitions (e.g. 'path to') should be processed as follows:
  # - If their names and codes are the same, only the last definition is used; other definitions are ignored and will not compile.
  # - 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.
  if name != '' and code.size == 8 and (not @commands.has_key?(name) or @commands[name][1] == code)
    @commands[name] = [name, code, parameters]
    node.each_element('parameter') do |pnode|
      _addnamecode(pnode, parameters)
    end
  end
end

#_addnamecode(node, collection) ⇒ Object



344
345
346
347
348
349
350
# File 'lib/osax.rb', line 344

def _addnamecode(node, collection)
  name = _name(node.attributes['name'])
  code = _code(node.attributes['code'])
  if name != '' and code.size == 4 and not collection.include?([name, code])
    collection.push([name, code])
  end
end

#_code(s) ⇒ Object



338
339
340
341
342
# File 'lib/osax.rb', line 338

def _code(s)
  return s.unpack('U*').collect do |c| # unpack UTF8-encoded byte string
    OSAX::UTF8ToMacRoman.fetch(c)
  end .pack('C*') # pack as MacRoman-encoded byte string (four- or eight-char code)
end

#_name(s) ⇒ Object



307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
# File 'lib/osax.rb', line 307

def _name(s)
  # Read a MacRoman-encoded Pascal keyword string.
  if not @@_name_cache.has_key?(s)
    legal = LegalFirst
    res = ''
    s.split(//).each do |c|
      if legal[c]
        res += c
      else
        case c
        when ' ', '-', '/'
          res += '_'
        when '&'
          res += 'and'
        else
          if res == ''
            res = '_'
          end
          res += "0x#{c.unpack('HXh')}"
        end
      end
      legal = LegalRest
    end
    if res[0, 3] == 'AS_' or @@_reserved_keywords.has_key?(res) or res[0, 1] == '_'
      res += '_'
    end
    @@_name_cache[s] = res
  end
  return @@_name_cache[s]
end

#commandsObject



294
295
296
# File 'lib/osax.rb', line 294

def commands
  return @commands.values
end

#parse(xml) ⇒ Object



367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
# File 'lib/osax.rb', line 367

def parse(xml)
  # Extract name-code mappings from an sdef.
  #
  # xml : String -- sdef data
  xml = REXML::Document.new(xml)
  xml.root.each_element('suite/*') do |node|
    begin
      if ['command', 'event'].include?(node.name)
        _addcommand(node)
      elsif ['class', 'record-type', 'value-type'].include?(node.name)
        _addnamecode(node, @classes)
        node.each_element('property') do |prop|
          _addnamecode(prop, @properties)
        end
        if node.name == 'class' # elements
          name = node.attributes['plural']
          if name == nil
            name = node.attributes['name']
            name = "#{name}s" if name != nil
          end
          name = _name(name)
          code = _code(node.attributes['code'])
          if name != '' and code.size == 4
            @elements.push([name, code])
          end
        end
      elsif node.name == 'enumeration'
        node.each_element('enumerator') do |enum|
          _addnamecode(enum, @enumerators)
        end
      end
    rescue # ignore problem definitions
    end
  end
end

#parse_file(path) ⇒ Object



403
404
405
406
407
408
# File 'lib/osax.rb', line 403

def parse_file(path)
  # Extract name-code mappings from an sdef.
  #
  # path :  String -- path to .sdef file
  parse(AE.copy_scripting_definition(path))
end