module Chroma module RgbGenerator class FromString < Base # Returns the regex matchers and rgb generation classes for various # string color formats. # # @api private # @return [Hash] def self.matchers @matchers ||= begin # TinyColor.js matchers css_int = '[-\\+]?\\d+%?' css_num = '[-\\+]?\\d*\\.\\d+%?' css_unit = "(?:#{css_num})|(?:#{css_int})" permissive_prefix = '[\\s|\\(]+(' permissive_delim = ')[,|\\s]+(' permissive_suffix = ')\\s*\\)?' permissive_match3 = "#{permissive_prefix}#{[css_unit] * 3 * permissive_delim}#{permissive_suffix}" permissive_match4 = "#{permissive_prefix}#{[css_unit] * 4 * permissive_delim}#{permissive_suffix}" hex_match = '[0-9a-fA-F]' { rgb: { regex: /rgb#{permissive_match3}/, class_name: :FromRgbValues }, rgba: { regex: /rgba#{permissive_match4}/, class_name: :FromRgbValues }, hsl: { regex: /hsl#{permissive_match3}/, class_name: :FromHslValues }, hsla: { regex: /hsla#{permissive_match4}/, class_name: :FromHslValues }, hsv: { regex: /hsv#{permissive_match3}/, class_name: :FromHsvValues }, hsva: { regex: /hsva#{permissive_match4}/, class_name: :FromHsvValues }, hex3: { regex: /^#?#{"(#{hex_match}{1})" * 3}$/, class_name: :FromHexStringValues, builder: :from_hex3 }, hex6: { regex: /^#?#{"(#{hex_match}{2})" * 3}$/, class_name: :FromHexStringValues, builder: :from_hex6 }, hex8: { regex: /^#?#{"(#{hex_match}{2})" * 4}$/, class_name: :FromHexStringValues, builder: :from_hex8 } }.freeze end end # @param format [Symbol] unused # @param input [String] input to parse def initialize(format, input) @input = normalize_input(input) end # Generates a {ColorModes::Rgb}. # @return [ColorModes::Rgb] def generate get_generator.generate end private def get_generator if color = Chroma.hex_from_name(@input) format = :name else format = nil color = @input end match = nil _, hash = matchers.find do |_, h| !(match = h[:regex].match(color)).nil? end if match.nil? raise Errors::UnrecognizedColor, "Unrecognized color `#{color}'" end build_generator(match[1..-1], hash[:class_name], hash[:builder], format) end def build_generator(args, class_name, builder, format) builder ||= :new klass = RgbGenerator.const_get(class_name) klass.__send__(builder, *([format] + args)) end def normalize_input(input) input.clone.tap do |str| str.strip! str.downcase! end end def matchers self.class.matchers end end end end