module UnitConversion INTEGER_REGEX = /-?[0-9]+/ DECIMAL_REGEX = /(?:-?[0-9]+)?\.[0-9]+/ RATIONAL_REGEX = /-?(?:[0-9]+ )?[0-9]+\/[0-9]+/ UNIT_REGEX = /[\[\]a-zA-Z][\[\]a-zA-Z\/.\-()0-9 ]*/ UNIT_PARSING_REGEX = /^(?#{INTEGER_REGEX}|#{DECIMAL_REGEX}|#{RATIONAL_REGEX})(?:\s+(?#{UNIT_REGEX}))?$/ STANDARD_UNIT_ALIASES = { '[cup_us]': %w(cup cups c), '[tbs_us]': %w(tablespoon tablespoons tbsp tbs), '[tsp_us]': %w(teaspoon teaspoons tsp), '[oz_av]': %w(ounce ounces oz), '[lb_av]': %w(pound pounds lb lbs), '[pt_us]': %w(pint pints), '[qt_us]': %w(quart quarts qt), '[gal_us]': %w(gallon gallons ga), '[foz_us]': %w(foz floz), } METRIC_UNIT_ALIASES = { g: %w(gram grams), kg: %w(kilograms kilogram), ml: %w(milliliter milliliters), cl: %w(centiliter centiliters), dl: %w(deciliter deciliters), l: %w(liter liters), m: %w(meter meters), cm: %w(centimeter centimeters) } UNIT_ALIASES = STANDARD_UNIT_ALIASES.merge(METRIC_UNIT_ALIASES) UNIT_ALIAS_MAP = Hash[UNIT_ALIASES.map { |unit, values| values.map { |v| [v, unit] } }.flatten(1)] # map that gives comfortable ranges for a given set of units UNIT_RANGES = { '[tsp_us]': (0.125...3.0), '[tbs_us]': (0.5...4.0), '[cup_us]': (0.25...4.0), '[qt_us]': (1.0..3.9), '[gal_us]': (0.5..9999), '[oz_av]': (0..16), '[lb_av]': (1.0..9999), g: (1.0..750), kg: (0.5..9999), ml: (1.0..750), l: (0.5..9999) } UNIT_ORDERS = { standard_volume: [ :'[tsp_us]', :'[tbs_us]', :'[cup_us]', :'[qt_us]', :'[gal_us]' ], metric_volume: [ :ml, :l ], standard_mass: [ :'[oz_av]', :'[lb_av]' ], metric_mass: [ :g, :kg ] } end