Class: Unitsml::Parser

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

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(text) ⇒ Parser

Returns a new instance of Parser.



7
8
9
10
11
12
13
# File 'lib/unitsml/parser.rb', line 7

def initialize(text)
  @regexp = %r{(quantity|name|symbol|multiplier):\s*}
  @text = extract_equation(text)
  @orig_text = @text
  @text = @text.gsub("", "-")
  post_extras
end

Instance Attribute Details

#textObject

Returns the value of attribute text.



5
6
7
# File 'lib/unitsml/parser.rb', line 5

def text
  @text
end

Instance Method Details

#parseObject



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/unitsml/parser.rb', line 15

def parse
  nodes = Parse.new.parse(text)
  transformed = Transform.new.apply(nodes)
  formula_value = transformed.is_a?(Formula) ? transformed.value : [transformed].flatten
  formula = Formula.new(
    formula_value,
    explicit_value: @extras_hash,
    root: true,
    orig_text: @orig_text,
    norm_text: text,
  )
  update_units_exponents(formula.value, false)
  formula.value.first.only_instance = true if text.end_with?("-")
  formula
end

#parse_extras(text) ⇒ Object



66
67
68
69
70
71
# File 'lib/unitsml/parser.rb', line 66

def parse_extras(text)
  return nil unless @regexp.match?(text)

  key, _, value = text&.partition(":")
  @extras_hash[key&.to_sym] ||= value&.strip
end

#post_extrasObject



57
58
59
60
61
62
63
64
# File 'lib/unitsml/parser.rb', line 57

def post_extras
  return nil unless @regexp.match?(text)

  @extras_hash = {}
  texts_array = text&.split(",")&.map(&:strip)
  @text = texts_array&.shift
  texts_array&.map { |text| parse_extras(text) }
end

#update_units_exponents(array, inverse, sqrt = false) ⇒ Object



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
# File 'lib/unitsml/parser.rb', line 31

def update_units_exponents(array, inverse, sqrt = false)
  array.each do |object|
    if object.is_a?(Sqrt)
      object = object.value
      if object.respond_to?(:power_numerator)
        object.power_numerator = "0.5"
      else
        update_units_exponents([object], inverse, true)
      end
    end

    case object
    when Unit
      next object.power_numerator = "0.5" if sqrt
      next unless inverse

      exponent = inverse ? "-#{object&.power_numerator || '1'}" : object.power_numerator
      object.power_numerator = exponent&.sub(/^--+/, "")
    when Dimension then object.power_numerator = "0.5" if sqrt
    when Extender then inverse = !inverse if ["/", "//"].any?(object.symbol)
    when Formula then update_units_exponents(object.value, inverse)
    when Fenced then update_units_exponents([object.value], inverse, sqrt)
    end
  end
end