Sha256: af18e5d283be4c9b1b341a5ef746e0e523245dbf063ede16b5ae3c41a1e03963

Contents?: true

Size: 1.91 KB

Versions: 11

Compression:

Stored size: 1.91 KB

Contents

module I18n
  module Tasks
    module SplitKey
      extend self

      # split a key by dots (.)
      # dots inside braces or parenthesis are not split on
      #
      # split_key 'a.b'      # => ['a', 'b']
      # split_key 'a.#{b.c}' # => ['a', '#{b.c}']
      # split_key 'a.b.c', 2 # => ['a', 'b.c']
      def split_key(key, max = Float::INFINITY)
        parts = []
        pos   = 0
        return [key] if max == 1
        key_parts(key) do |part|
          parts << part
          pos += part.length + 1
          if parts.length + 1 >= max
            parts << key.from(pos) unless pos == key.length
            break
          end
        end
        parts
      end

      def last_key_part(key)
        last = nil
        key_parts(key) { |part| last = part }
        last
      end

      # yield each key part
      # dots inside braces or parenthesis are not split on
      def key_parts(key, &block)
        return enum_for(:key_parts, key) unless block
        nesting = PARENS
        counts  = PARENS_ZEROS # dup'd later if key contains parenthesis
        delim   = '.'.freeze
        from    = to = 0
        key.each_char do |char|
          if char == delim && PARENS_ZEROS == counts
            block.yield key[from...to]
            from = to = (to + 1)
          else
            nest_i, nest_inc = nesting[char]
            if nest_i
              counts         = counts.dup if counts.frozen?
              counts[nest_i] += nest_inc
            end
            to += 1
          end
        end
        block.yield(key[from...to]) if from < to && to <= key.length
        true
      end

      PARENS       = %w({} [] ()).inject({}) { |h, s|
        i              = h.size / 2
        h[s[0].freeze] = [i, 1].freeze
        h[s[1].freeze] = [i, -1].freeze
        h
      }.freeze
      PARENS_ZEROS = Array.new(PARENS.size, 0).freeze
      private_constant :PARENS
      private_constant :PARENS_ZEROS
    end
  end
end

Version data entries

11 entries across 11 versions & 1 rubygems

Version Path
i18n-tasks-0.8.3 lib/i18n/tasks/split_key.rb
i18n-tasks-0.8.2 lib/i18n/tasks/split_key.rb
i18n-tasks-0.8.1 lib/i18n/tasks/split_key.rb
i18n-tasks-0.8.0 lib/i18n/tasks/split_key.rb
i18n-tasks-0.7.13 lib/i18n/tasks/split_key.rb
i18n-tasks-0.7.12 lib/i18n/tasks/split_key.rb
i18n-tasks-0.7.11 lib/i18n/tasks/split_key.rb
i18n-tasks-0.7.10 lib/i18n/tasks/split_key.rb
i18n-tasks-0.7.9 lib/i18n/tasks/split_key.rb
i18n-tasks-0.7.8 lib/i18n/tasks/split_key.rb
i18n-tasks-0.7.7 lib/i18n/tasks/split_key.rb