Class: Measures::ElmParser

Inherits:
Object
  • Object
show all
Defined in:
lib/measure-loader/elm_parser.rb

Class Method Summary collapse

Class Method Details

.generate_localid_to_type_map(doc) ⇒ Object



58
59
60
61
62
63
64
65
# File 'lib/measure-loader/elm_parser.rb', line 58

def self.generate_localid_to_type_map(doc)
  localid_to_type_map = {}
  @fields.each do |field|
    nodes = doc.css(field + '[localId][xsi|type]')
    nodes.each {|node| localid_to_type_map[node['localId']] = node['xsi:type']}
  end
  return localid_to_type_map
end

.parse(doc) ⇒ Object



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# File 'lib/measure-loader/elm_parser.rb', line 6

def self.parse(doc)
  localid_to_type_map = generate_localid_to_type_map(doc)
  ret = {
    statements: [],
    identifier: {}
  }
  # extract library identifier data
  ret[:identifier][:id] = doc.css("identifier").attr("id").value
  ret[:identifier][:version] = doc.css("identifier").attr("version").value

  # extracts the fields of type "annotation" and their children.
  annotations = doc.css("annotation")
  annotations.each do |node|
    node, define_name = parse_node(node, localid_to_type_map)
    unless define_name.nil?
      node[:define_name] = define_name
      ret[:statements] << node
    end
  end
  ret
end

.parse_node(node, localid_to_type_map) ⇒ Object

Recursive function that traverses the annotation tree and constructs a representation that will be compatible with the front end.



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/measure-loader/elm_parser.rb', line 30

def self.parse_node(node, localid_to_type_map)
  ret = {
    children: []
  }
  define_name = nil
  node.children.each do |child|
    if child.is_a?(Nokogiri::XML::Text) # leaf node
      clause_text = child.content.gsub(/\t/, "  ")
      clause = {
        text: clause_text
      }
      clause[:ref_id] = child['r'] unless child['r'].nil?
      ret[:children] << clause
      define_name = clause_text.split("\"")[1] if clause_text.strip.starts_with?("define")
    else
      node_type = localid_to_type_map[child['r']] unless child['r'].nil?
      # Parses the current child recursively. child_define_name will bubble up to indicate which
      # statement is currently being traversed.
      node, child_define_name = parse_node(child, localid_to_type_map)
      node[:node_type] = node_type  unless node_type.nil?
      node[:ref_id] = child['r'] unless child['r'].nil?
      ret[:children] << node
      define_name = child_define_name unless child_define_name.nil?
    end
  end
  return ret, define_name
end