Class: Pincerna::UnitConversion

Inherits:
Base
  • Object
show all
Defined in:
lib/pincerna/unit_conversion.rb

Overview

Converts a value from a unit to another.

Constant Summary

MATCHER =

The expression to match.

/^
  (?<value>([+-]?)(\d+)([.,]\d+)?)
  \s+
  (?<from>\S+?)
  \s+
  (to\s+)?
  (?<to>\S+)
  (?<rate>\s+with\s+rate)?
  (?<split>\s+split\s+units)?
$/mix
RELEVANT_MATCHES =

Relevant groups in the match.

{
  "value" => ->(context, value) { context.round_float(value.gsub(",", ".").to_f) },
  "from" => ->(_, value) { value },
  "to" => ->(_, value) { value },
  "rate" => ->(_, value) { !value.nil? }, # If show conversion rate
  "split" => ->(_, value) { !value.nil? } # If group unit for ft+in and lb+oz
}
ICON =

The icon to show for each feedback item.

Pincerna::Base::ROOT + "/images/unit.png"

Constants inherited from Base

Base::CACHE_ROOT, Base::FULL_NAME, Base::ROOT, Base::TYPES, Base::WORKFLOW_ROOT

Instance Attribute Summary

Attributes inherited from Base

#format, #format_content_type, #output

Class Method Summary (collapse)

Instance Method Summary (collapse)

Methods inherited from Base

#add_feedback_item, execute!, #filter, #format_float, #initialize, #output_feedback, #round_float

Constructor Details

This class inherits a constructor from Pincerna::Base

Class Method Details

+ (Object) define_unit(name, definition, aliases)

Defines a new unit.

Parameters:

  • name (String)

    The name of the unit.

  • definition (String)

    The definition of the unit.

  • aliases (Array)

    The aliases of this unit.



39
40
41
42
43
44
# File 'lib/pincerna/unit_conversion.rb', line 39

def self.define_unit(name, definition, aliases)
  RubyUnits::Unit.define(name) do |unit|
    unit.definition = RubyUnits::Unit.new(definition)
    unit.aliases = aliases
  end
end

Instance Method Details

- (String) check_temperature(unit)

Checks if a unit is a temperature and prepend “temp” if needed.

Parameters:

  • unit (String)

    The unit to check.

Returns:

  • (String)

    The adjusted unit.



77
78
79
80
# File 'lib/pincerna/unit_conversion.rb', line 77

def check_temperature(unit)
  unit = unit.gsub("°", "")
  /^[CFKR]$/.match(unit.upcase) ? "temp#{unit.upcase}" : unit
end

- (String|NilClass) convert_value(value, from, to)

Converts a value from a unit to another.

Parameters:

  • value (Float)

    The value to convert.

  • from (String)

    The origin unit.

  • to (String)

    The target unit.

Returns:

  • (String|NilClass)

    The converted unit or nil if the conversion failed.



88
89
90
# File 'lib/pincerna/unit_conversion.rb', line 88

def convert_value(value, from, to)
  Unit.new("#{value} #{from}").convert_to(to)
end

- (String|Float) format_value(value, modifier = nil, precision = 3)

Formats a value.

Parameters:

  • value (String)

    The value to format.

  • modifier (Boolean|Symbol) (defaults to: nil)

    If to use multiple units for ft (ft+in) and lb/oz (lb+oz). If :raw, only the unitless (float) value is returned.

  • precision (Fixnum) (defaults to: 3)

    The precision to use for rounding.

Returns:

  • (String|Float)

    The formatted value or the unitless value.



98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/pincerna/unit_conversion.rb', line 98

def format_value(value, modifier = nil, precision = 3)
  rounded = round_float(value.scalar.to_f, precision)

  if modifier != :raw then
    format = "%0.#{precision}f"
    units = value.units

    if modifier && units =~ /ft|oz|lb/ then
      format = units == "ft" ? :ft : :lbs
    elsif rounded.to_i == rounded then
      format = "%0.0f"
    end

    value.to_s(format).gsub(", ", " ").gsub(/ temp([CFKR])/, "°\\1")
  else
    rounded
  end
end

- (Hash|NilClass) perform_filtering(value, from, to, with_rate, multiple)

Converts a value from a unit to another.

Parameters:

  • value (Float)

    The value to convert.

  • from (String)

    The origin unit.

  • to (String)

    The target unit.

  • with_rate (Boolean)

    If to return the conversion rate in the results.

  • multiple (Boolean)

    If to use multiple units for ft (ft+in) and lb/oz (lb+oz).

Returns:

  • (Hash|NilClass)

    The converted data or nil if the conversion failed.



54
55
56
57
58
59
# File 'lib/pincerna/unit_conversion.rb', line 54

def perform_filtering(value, from, to, with_rate, multiple)
  from = check_temperature(from)
  to = check_temperature(to)
  converted = convert_value(value, from, to)
  converted ? {from: from, to: to, value: convert_value(value, from, from), unit: convert_value(1, from, from), result: converted, rate: convert_value(1, from, to), with_rate: with_rate, multiple: multiple} : nil
end

- (Array) process_results(results)

Processes items to obtain feedback items.

Parameters:

  • results (Hash)

    The items to process.

Returns:

  • (Array)

    The feedback items.



65
66
67
68
69
70
71
# File 'lib/pincerna/unit_conversion.rb', line 65

def process_results(results)
  multiple = results[:multiple]
  title = "#{format_value(results[:value], multiple)} = #{format_value(results[:result], multiple)}"
  title << " (#{format_value(results[:unit], multiple)} = #{format_value(results[:rate], multiple)})" if results[:with_rate]

  [{title: title, arg: format_value(results[:result], :raw), subtitle: "Action this item to copy the converted amount on the clipboard.", icon: ICON}]
end