This commit is contained in:
@@ -0,0 +1,187 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Sass
|
||||
module Value
|
||||
class Number
|
||||
# The {Unit} module.
|
||||
module Unit
|
||||
CONVERSIONS = {
|
||||
# Length
|
||||
'in' => {
|
||||
'in' => Rational(1),
|
||||
'cm' => Rational(1, 2.54),
|
||||
'pc' => Rational(1, 6),
|
||||
'mm' => Rational(1, 25.4),
|
||||
'q' => Rational(1, 101.6),
|
||||
'pt' => Rational(1, 72),
|
||||
'px' => Rational(1, 96)
|
||||
},
|
||||
'cm' => {
|
||||
'in' => Rational(2.54),
|
||||
'cm' => Rational(1),
|
||||
'pc' => Rational(2.54, 6),
|
||||
'mm' => Rational(1, 10),
|
||||
'q' => Rational(1, 40),
|
||||
'pt' => Rational(2.54, 72),
|
||||
'px' => Rational(2.54, 96)
|
||||
},
|
||||
'pc' => {
|
||||
'in' => Rational(6),
|
||||
'cm' => Rational(6, 2.54),
|
||||
'pc' => Rational(1),
|
||||
'mm' => Rational(6, 25.4),
|
||||
'q' => Rational(6, 101.6),
|
||||
'pt' => Rational(1, 12),
|
||||
'px' => Rational(1, 16)
|
||||
},
|
||||
'mm' => {
|
||||
'in' => Rational(25.4),
|
||||
'cm' => Rational(10),
|
||||
'pc' => Rational(25.4, 6),
|
||||
'mm' => Rational(1),
|
||||
'q' => Rational(1, 4),
|
||||
'pt' => Rational(25.4, 72),
|
||||
'px' => Rational(25.4, 96)
|
||||
},
|
||||
'q' => {
|
||||
'in' => Rational(101.6),
|
||||
'cm' => Rational(40),
|
||||
'pc' => Rational(101.6, 6),
|
||||
'mm' => Rational(4),
|
||||
'q' => Rational(1),
|
||||
'pt' => Rational(101.6, 72),
|
||||
'px' => Rational(101.6, 96)
|
||||
},
|
||||
'pt' => {
|
||||
'in' => Rational(72),
|
||||
'cm' => Rational(72, 2.54),
|
||||
'pc' => Rational(12),
|
||||
'mm' => Rational(72, 25.4),
|
||||
'q' => Rational(72, 101.6),
|
||||
'pt' => Rational(1),
|
||||
'px' => Rational(3, 4)
|
||||
},
|
||||
'px' => {
|
||||
'in' => Rational(96),
|
||||
'cm' => Rational(96, 2.54),
|
||||
'pc' => Rational(16),
|
||||
'mm' => Rational(96, 25.4),
|
||||
'q' => Rational(96, 101.6),
|
||||
'pt' => Rational(4, 3),
|
||||
'px' => Rational(1)
|
||||
},
|
||||
|
||||
# Rotation
|
||||
'deg' => {
|
||||
'deg' => Rational(1),
|
||||
'grad' => Rational(9, 10),
|
||||
'rad' => Rational(180, Math::PI),
|
||||
'turn' => Rational(360)
|
||||
},
|
||||
'grad' => {
|
||||
'deg' => Rational(10, 9),
|
||||
'grad' => Rational(1),
|
||||
'rad' => Rational(200, Math::PI),
|
||||
'turn' => Rational(400)
|
||||
},
|
||||
'rad' => {
|
||||
'deg' => Rational(Math::PI, 180),
|
||||
'grad' => Rational(Math::PI, 200),
|
||||
'rad' => Rational(1),
|
||||
'turn' => Rational(Math::PI * 2)
|
||||
},
|
||||
'turn' => {
|
||||
'deg' => Rational(1, 360),
|
||||
'grad' => Rational(1, 400),
|
||||
'rad' => Rational(1, Math::PI * 2),
|
||||
'turn' => Rational(1)
|
||||
},
|
||||
|
||||
# Time
|
||||
's' => {
|
||||
's' => Rational(1),
|
||||
'ms' => Rational(1, 1000)
|
||||
},
|
||||
'ms' => {
|
||||
's' => Rational(1000),
|
||||
'ms' => Rational(1)
|
||||
},
|
||||
|
||||
# Frequency
|
||||
'Hz' => {
|
||||
'Hz' => Rational(1),
|
||||
'kHz' => Rational(1000)
|
||||
},
|
||||
'kHz' => {
|
||||
'Hz' => Rational(1, 1000),
|
||||
'kHz' => Rational(1)
|
||||
},
|
||||
|
||||
# Pixel density
|
||||
'dpi' => {
|
||||
'dpi' => Rational(1),
|
||||
'dpcm' => Rational(2.54),
|
||||
'dppx' => Rational(96)
|
||||
},
|
||||
'dpcm' => {
|
||||
'dpi' => Rational(1, 2.54),
|
||||
'dpcm' => Rational(1),
|
||||
'dppx' => Rational(96, 2.54)
|
||||
},
|
||||
'dppx' => {
|
||||
'dpi' => Rational(1, 96),
|
||||
'dpcm' => Rational(2.54, 96),
|
||||
'dppx' => Rational(1)
|
||||
}
|
||||
}.freeze
|
||||
|
||||
UNITS_BY_TYPE = {
|
||||
time: %w[s ms],
|
||||
frequency: %w[Hz kHz],
|
||||
'pixel density': %w[dpi dpcm dppx]
|
||||
}.freeze
|
||||
|
||||
TYPES_BY_UNIT = UNITS_BY_TYPE.each_with_object({}) do |(key, values), hash|
|
||||
values.each do |value|
|
||||
hash[value] = key
|
||||
end
|
||||
end
|
||||
|
||||
module_function
|
||||
|
||||
def conversion_factor(unit1, unit2)
|
||||
return 1 if unit1 == unit2
|
||||
|
||||
CONVERSIONS.dig(unit1, unit2)
|
||||
end
|
||||
|
||||
def canonicalize_units(units)
|
||||
return units if units.empty?
|
||||
|
||||
if units.length == 1
|
||||
type = TYPES_BY_UNIT[units.first]
|
||||
return type.nil? ? units : [UNITS_BY_TYPE[type].first]
|
||||
end
|
||||
|
||||
units.map do |unit|
|
||||
type = TYPES_BY_UNIT[unit]
|
||||
type.nil? ? units : [UNITS_BY_TYPE[type].first]
|
||||
end.sort
|
||||
end
|
||||
|
||||
def canonical_multiplier(units)
|
||||
units.reduce(1) do |multiplier, unit|
|
||||
multiplier * canonical_multiplier_for_unit(unit)
|
||||
end
|
||||
end
|
||||
|
||||
def canonical_multiplier_for_unit(unit)
|
||||
inner_map = CONVERSIONS[unit]
|
||||
inner_map.nil? ? 1 : 1 / inner_map.values.first
|
||||
end
|
||||
end
|
||||
|
||||
private_constant :Unit
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user