yaml-translator 0.8.4 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +7 -0
- data/lib/yaml-translator.rb +0 -1
- data/lib/yaml-translator/adapters/google_translate_adapter.rb +3 -0
- data/lib/yaml-translator/adapters/noop_adapter.rb +3 -0
- data/lib/yaml-translator/context.rb +7 -2
- data/lib/yaml-translator/locale.rb +65 -24
- data/lib/yaml-translator/translator.rb +4 -10
- data/lib/yaml-translator/version.rb +1 -1
- data/spec/yaml-translator/context_spec.rb +16 -0
- data/spec/yaml-translator/locale_spec.rb +4 -4
- data/spec/yaml-translator/translator_spec.rb +4 -4
- metadata +3 -8
- data/lib/yaml-translator/structure.rb +0 -5
- data/lib/yaml-translator/structure/single_key.rb +0 -27
- data/lib/yaml-translator/structure/tree.rb +0 -35
- data/spec/yaml-translator/structure/single_key.rb +0 -8
- data/spec/yaml-translator/structure/tree_spec.rb +0 -8
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA1:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: da4cda7e0c0b4e1d18d9263bc51e018e660b0902
         | 
| 4 | 
            +
              data.tar.gz: 66dbc7e06c1561486815e1e0c266cbaf54146057
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 92b3ccd4969f1df29d8a95b7110e2ecf24d04fb0066b5803e5ace67193a92ad3d6ba99c8992adb4b413c61bb317c6c543efe3016870a808df441de16ff9e2fe2
         | 
| 7 | 
            +
              data.tar.gz: ac073cf2fb71577ecc7376c5e1a4799c8de9ad37668220543e9f120f02284e01b62ff2bb58cf25daaa697c0cbbfa54cb081293772ed1e71fdf9bd55c13d92392
         | 
    
        data/Gemfile.lock
    CHANGED
    
    
    
        data/README.md
    CHANGED
    
    | @@ -48,6 +48,13 @@ diff_locale = translator.file("/path/to/before/en.yml").diff("/path/to/after/en. | |
| 48 48 | 
             
            diff_locale.to(:ja).save
         | 
| 49 49 | 
             
            ```
         | 
| 50 50 |  | 
| 51 | 
            +
            translate into multiple languages
         | 
| 52 | 
            +
             | 
| 53 | 
            +
            ```ruby
         | 
| 54 | 
            +
            diff_locale = translator.file("/path/to/before/en.yml").diff("/path/to/after/en.yml")
         | 
| 55 | 
            +
            diff_locale.all(%w(ja en)).each { |r| r.save }
         | 
| 56 | 
            +
            ```
         | 
| 57 | 
            +
             | 
| 51 58 | 
             
            ## Run the test
         | 
| 52 59 |  | 
| 53 60 | 
             
            	bundle install
         | 
    
        data/lib/yaml-translator.rb
    CHANGED
    
    
| @@ -3,6 +3,9 @@ require 'easy_translate' | |
| 3 3 | 
             
            module YamlTranslator
         | 
| 4 4 | 
             
              module Adapters
         | 
| 5 5 | 
             
                class GoogleTranslateAdapter < BaseAdapter
         | 
| 6 | 
            +
                  # Translate for locale texts
         | 
| 7 | 
            +
                  # @param [Hash] locale texts of translate target
         | 
| 8 | 
            +
                  # @return [Hash] locale texts
         | 
| 6 9 | 
             
                  def translate(values, options={})
         | 
| 7 10 | 
             
                    keys = []
         | 
| 8 11 | 
             
                    texts = []
         | 
| @@ -4,8 +4,13 @@ module YamlTranslator | |
| 4 4 | 
             
                  @locale = locale
         | 
| 5 5 | 
             
                  @translator = translator
         | 
| 6 6 | 
             
                end
         | 
| 7 | 
            -
             | 
| 8 | 
            -
             | 
| 7 | 
            +
             | 
| 8 | 
            +
                def to(target)
         | 
| 9 | 
            +
                  @locale.translate(@translator, to: target)
         | 
| 10 | 
            +
                end
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                def all(targets)
         | 
| 13 | 
            +
                  targets.map { |target| @locale.translate(@translator, to: target) }
         | 
| 9 14 | 
             
                end
         | 
| 10 15 | 
             
              end
         | 
| 11 16 |  | 
| @@ -1,37 +1,50 @@ | |
| 1 1 | 
             
            require 'yaml'
         | 
| 2 | 
            +
            require 'ostruct'
         | 
| 2 3 | 
             
            require 'diff/lcs'
         | 
| 3 4 |  | 
| 4 5 | 
             
            module YamlTranslator
         | 
| 5 | 
            -
              class Locale
         | 
| 6 | 
            +
              class Locale < OpenStruct
         | 
| 7 | 
            +
                attr_reader :lang
         | 
| 6 8 |  | 
| 7 | 
            -
                 | 
| 9 | 
            +
                class << self
         | 
| 10 | 
            +
                  def load(s)
         | 
| 11 | 
            +
                    self.new(YAML.load(s))
         | 
| 12 | 
            +
                  end
         | 
| 8 13 |  | 
| 9 | 
            -
             | 
| 10 | 
            -
             | 
| 11 | 
            -
                   | 
| 14 | 
            +
                  def load_file(file)
         | 
| 15 | 
            +
                    load(File.open(file, &:read))
         | 
| 16 | 
            +
                  end
         | 
| 17 | 
            +
                end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                def initialize(config)
         | 
| 20 | 
            +
                  super(config)
         | 
| 21 | 
            +
                  @lang = config.keys.first.to_sym # FIXME check support language
         | 
| 12 22 | 
             
                end
         | 
| 13 23 |  | 
| 14 24 | 
             
                def translate(translator, options={})
         | 
| 15 | 
            -
                   | 
| 25 | 
            +
                  result = {}
         | 
| 26 | 
            +
                  values = to_h
         | 
| 27 | 
            +
                  translated_values = translator.translate(compact_of(values[@lang]), options)
         | 
| 28 | 
            +
                  result[options[:to]] = tree_of(translated_values)
         | 
| 29 | 
            +
                  Locale.new(result)
         | 
| 16 30 | 
             
                end
         | 
| 17 31 |  | 
| 18 | 
            -
                def diff( | 
| 32 | 
            +
                def diff(other_locale)
         | 
| 19 33 | 
             
                  before_seq = to_single_key_hash.map { |k, v| "#{k}: #{v}" }
         | 
| 20 | 
            -
                  after_seq =  | 
| 34 | 
            +
                  after_seq = other_locale.to_single_key_hash.map { |k, v| "#{k}: #{v}" }
         | 
| 21 35 | 
             
                  diffs = Diff::LCS.diff(before_seq, after_seq).flatten.map do |operation|
         | 
| 22 36 | 
             
                    type, position, element = *operation
         | 
| 23 37 | 
             
                    next if type == '-'
         | 
| 24 38 | 
             
                    key, text = *element.split(':')
         | 
| 25 39 | 
             
                    [key, text.strip]
         | 
| 26 40 | 
             
                  end
         | 
| 27 | 
            -
                   | 
| 28 | 
            -
                  Locale.new(single_key_hash.to_tree, lang)
         | 
| 41 | 
            +
                  Locale.new(tree_of(Hash[diffs.compact]))
         | 
| 29 42 | 
             
                end
         | 
| 30 43 |  | 
| 31 | 
            -
                def merge( | 
| 44 | 
            +
                def merge(other_locale)
         | 
| 32 45 | 
             
                  s = to_single_key_hash
         | 
| 33 | 
            -
                  o =  | 
| 34 | 
            -
                  Locale.new(s.merge(o) | 
| 46 | 
            +
                  o = other_locale.to_single_key_hash
         | 
| 47 | 
            +
                  Locale.new(tree_of(s.merge(o)))
         | 
| 35 48 | 
             
                end
         | 
| 36 49 |  | 
| 37 50 | 
             
                def merge_to(locale)
         | 
| @@ -56,27 +69,55 @@ module YamlTranslator | |
| 56 69 | 
             
                  save(dir)
         | 
| 57 70 | 
             
                end
         | 
| 58 71 |  | 
| 72 | 
            +
                # Covert to a flatten hash
         | 
| 59 73 | 
             
                def to_single_key_hash
         | 
| 60 | 
            -
                   | 
| 74 | 
            +
                  compact_of(to_h, KeyPath.new)
         | 
| 61 75 | 
             
                end
         | 
| 62 76 |  | 
| 63 77 | 
             
                def to_s
         | 
| 64 | 
            -
                  YAML.dump( | 
| 78 | 
            +
                  YAML.dump(tree_of(compact_of(to_h)))
         | 
| 65 79 | 
             
                end
         | 
| 66 80 |  | 
| 67 | 
            -
                 | 
| 68 | 
            -
                  def load(s)
         | 
| 69 | 
            -
                    yaml = YAML.load(s)
         | 
| 70 | 
            -
                    lang = yaml.keys.first # FIXME check support language
         | 
| 71 | 
            -
                    self.new(yaml, lang)
         | 
| 72 | 
            -
                  end
         | 
| 81 | 
            +
                private
         | 
| 73 82 |  | 
| 74 | 
            -
             | 
| 75 | 
            -
             | 
| 83 | 
            +
                # Covert to a flatten hash
         | 
| 84 | 
            +
                def compact_of(values={}, path=KeyPath.new)
         | 
| 85 | 
            +
                  result = {}
         | 
| 86 | 
            +
                  values.each_with_index do |(i, v)|
         | 
| 87 | 
            +
                    path.move_to(i)
         | 
| 88 | 
            +
                    if v.is_a?(Hash)
         | 
| 89 | 
            +
                      result.merge!(compact_of(v, path))
         | 
| 90 | 
            +
                    else
         | 
| 91 | 
            +
                      result[path.to_s] = v
         | 
| 92 | 
            +
                    end
         | 
| 93 | 
            +
                    path.leave
         | 
| 76 94 | 
             
                  end
         | 
| 95 | 
            +
                  result
         | 
| 77 96 | 
             
                end
         | 
| 78 97 |  | 
| 79 | 
            -
                 | 
| 98 | 
            +
                # Returning the flattened structure to the tree structure
         | 
| 99 | 
            +
                #
         | 
| 100 | 
            +
                # @param [Hash] values flatten Hash
         | 
| 101 | 
            +
                # @return [Hash] translated hash
         | 
| 102 | 
            +
                def tree_of(values)
         | 
| 103 | 
            +
                  result = {}
         | 
| 104 | 
            +
                  current = result
         | 
| 105 | 
            +
                  values.each do |k, v|
         | 
| 106 | 
            +
                    keys = k.to_s.split('.')
         | 
| 107 | 
            +
                    last_key = keys.pop
         | 
| 108 | 
            +
                    keys.each do |ks|
         | 
| 109 | 
            +
                      current = if current.key?(ks)
         | 
| 110 | 
            +
                                  current[ks]
         | 
| 111 | 
            +
                                else
         | 
| 112 | 
            +
                                  current[ks] = {}
         | 
| 113 | 
            +
                                  current[ks]
         | 
| 114 | 
            +
                                end
         | 
| 115 | 
            +
                    end
         | 
| 116 | 
            +
                    current[last_key] = v
         | 
| 117 | 
            +
                    current = result
         | 
| 118 | 
            +
                  end
         | 
| 119 | 
            +
                  result
         | 
| 120 | 
            +
                end
         | 
| 80 121 |  | 
| 81 122 | 
             
                def write_file(file_path)
         | 
| 82 123 | 
             
                  File.write(file_path, to_s)
         | 
| @@ -12,16 +12,10 @@ module YamlTranslator | |
| 12 12 |  | 
| 13 13 | 
             
                # Translate target
         | 
| 14 14 | 
             
                #
         | 
| 15 | 
            -
                # @param [ | 
| 16 | 
            -
                # @return [ | 
| 17 | 
            -
                def translate( | 
| 18 | 
            -
                   | 
| 19 | 
            -
                  translated_tree = translated.to_tree
         | 
| 20 | 
            -
             | 
| 21 | 
            -
                  result = {}
         | 
| 22 | 
            -
                  result[options[:to].to_s] = translated_tree[locale.lang]
         | 
| 23 | 
            -
             | 
| 24 | 
            -
                  Locale.new(result, options[:to])
         | 
| 15 | 
            +
                # @param [Hash] locale texts of translate target
         | 
| 16 | 
            +
                # @return [Hash] locale texts
         | 
| 17 | 
            +
                def translate(locale_texts, options={})
         | 
| 18 | 
            +
                  @adapter.translate(locale_texts, options)
         | 
| 25 19 | 
             
                end
         | 
| 26 20 |  | 
| 27 21 | 
             
                def string(s)
         | 
| @@ -0,0 +1,16 @@ | |
| 1 | 
            +
            describe YamlTranslator::Context do
         | 
| 2 | 
            +
              let(:lang_file) { File.join(File.dirname(__FILE__), '/../fixtures/en.yml') }
         | 
| 3 | 
            +
              let(:locale) { YamlTranslator::Locale.load_file(lang_file) }
         | 
| 4 | 
            +
              let(:adapter) { YamlTranslator::Adapters::NoopAdapter.new }
         | 
| 5 | 
            +
              let(:translator) { YamlTranslator::Translator.new(adapter) }
         | 
| 6 | 
            +
             | 
| 7 | 
            +
              describe '#all' do
         | 
| 8 | 
            +
                let(:context) { YamlTranslator::Context.new(locale, translator) }
         | 
| 9 | 
            +
                subject { context.all(%w(ja en)) }
         | 
| 10 | 
            +
                it 'should be translate all' do
         | 
| 11 | 
            +
                  expect(subject.size).to eq(2)
         | 
| 12 | 
            +
                  expect(subject[0].lang).to eq(:ja)
         | 
| 13 | 
            +
                  expect(subject[1].lang).to eq(:en)
         | 
| 14 | 
            +
                end
         | 
| 15 | 
            +
              end
         | 
| 16 | 
            +
            end
         | 
| @@ -13,7 +13,7 @@ describe YamlTranslator::Locale do | |
| 13 13 | 
             
              describe '#load' do
         | 
| 14 14 | 
             
                it 'should be load from string' do
         | 
| 15 15 | 
             
                  locale = YamlTranslator::Locale.load(lang_file_content)
         | 
| 16 | 
            -
                  expect(locale.lang).to eq( | 
| 16 | 
            +
                  expect(locale.lang).to eq(:en)
         | 
| 17 17 | 
             
                end
         | 
| 18 18 | 
             
              end
         | 
| 19 19 |  | 
| @@ -27,7 +27,7 @@ describe YamlTranslator::Locale do | |
| 27 27 | 
             
                end
         | 
| 28 28 | 
             
                it 'should be return flatten hash' do
         | 
| 29 29 | 
             
                  diff_locale = before_locale.diff(after_locale)
         | 
| 30 | 
            -
                  expect(diff_locale.lang).to eq( | 
| 30 | 
            +
                  expect(diff_locale.lang).to eq(:en)
         | 
| 31 31 | 
             
                  expect(diff_locale.to_single_key_hash).to eq(single_key_hash)
         | 
| 32 32 | 
             
                end
         | 
| 33 33 | 
             
              end
         | 
| @@ -50,14 +50,14 @@ describe YamlTranslator::Locale do | |
| 50 50 | 
             
                let(:merge_target_file) { File.join(File.dirname(__FILE__), '/../fixtures/merge_target.yml') }
         | 
| 51 51 | 
             
                it 'should be merge to yaml file' do
         | 
| 52 52 | 
             
                  merged = locale.merge_to_file(merge_target_file)
         | 
| 53 | 
            -
                  expect(merged | 
| 53 | 
            +
                  expect(merged['en']['target']).to eq('bar')
         | 
| 54 54 | 
             
                end
         | 
| 55 55 | 
             
              end
         | 
| 56 56 |  | 
| 57 57 | 
             
              describe '#merge_to_s' do
         | 
| 58 58 | 
             
                it 'should be merge to yaml formatted string' do
         | 
| 59 59 | 
             
                  merged = locale.merge_to_s("---\nen:\n  merge_to_s: ok?")
         | 
| 60 | 
            -
                  expect(merged | 
| 60 | 
            +
                  expect(merged['en']['merge_to_s']).to eq('ok?')
         | 
| 61 61 | 
             
                end
         | 
| 62 62 | 
             
              end
         | 
| 63 63 |  | 
| @@ -7,7 +7,7 @@ describe YamlTranslator::Translator do | |
| 7 7 | 
             
                  it 'translate files' do
         | 
| 8 8 | 
             
                    result = translator.file(path).to(:ja)
         | 
| 9 9 | 
             
                    expect(result.lang).to eq(:ja)
         | 
| 10 | 
            -
                    expect(result. | 
| 10 | 
            +
                    expect(result.config).to eq(expected_locale.config)
         | 
| 11 11 | 
             
                  end
         | 
| 12 12 | 
             
                end
         | 
| 13 13 | 
             
                context 'when zh-CN' do
         | 
| @@ -16,7 +16,7 @@ describe YamlTranslator::Translator do | |
| 16 16 | 
             
                  it 'translate files' do
         | 
| 17 17 | 
             
                    result = translator.file(path).to(:'zh-CN')
         | 
| 18 18 | 
             
                    expect(result.lang).to eq(:'zh-CN')
         | 
| 19 | 
            -
                    expect(result. | 
| 19 | 
            +
                    expect(result.config).to eq(expected_locale.config)
         | 
| 20 20 | 
             
                  end
         | 
| 21 21 | 
             
                end
         | 
| 22 22 | 
             
              end
         | 
| @@ -28,7 +28,7 @@ describe YamlTranslator::Translator do | |
| 28 28 | 
             
                  it 'translate yaml string' do
         | 
| 29 29 | 
             
                    result = translator.string(yaml_source).to(:ja)
         | 
| 30 30 | 
             
                    expect(result.lang).to eq(:ja)
         | 
| 31 | 
            -
                    expect(result. | 
| 31 | 
            +
                    expect(result.config).to eq(expected_locale.config)
         | 
| 32 32 | 
             
                  end
         | 
| 33 33 | 
             
                end
         | 
| 34 34 | 
             
                context 'when zh-CN' do
         | 
| @@ -37,7 +37,7 @@ describe YamlTranslator::Translator do | |
| 37 37 | 
             
                  it 'translate yaml string' do
         | 
| 38 38 | 
             
                    result = translator.string(yaml_source).to(:'zh-CN')
         | 
| 39 39 | 
             
                    expect(result.lang).to eq(:'zh-CN')
         | 
| 40 | 
            -
                    expect(result. | 
| 40 | 
            +
                    expect(result.config).to eq(expected_locale.config)
         | 
| 41 41 | 
             
                  end
         | 
| 42 42 | 
             
                end
         | 
| 43 43 | 
             
              end
         | 
    
        metadata
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: yaml-translator
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0. | 
| 4 | 
            +
              version: 0.9.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Noritaka Horio
         | 
| @@ -165,9 +165,6 @@ files: | |
| 165 165 | 
             
            - lib/yaml-translator/context.rb
         | 
| 166 166 | 
             
            - lib/yaml-translator/key_path.rb
         | 
| 167 167 | 
             
            - lib/yaml-translator/locale.rb
         | 
| 168 | 
            -
            - lib/yaml-translator/structure.rb
         | 
| 169 | 
            -
            - lib/yaml-translator/structure/single_key.rb
         | 
| 170 | 
            -
            - lib/yaml-translator/structure/tree.rb
         | 
| 171 168 | 
             
            - lib/yaml-translator/translator.rb
         | 
| 172 169 | 
             
            - lib/yaml-translator/version.rb
         | 
| 173 170 | 
             
            - spec/fixtures/diff/after/en.yml
         | 
| @@ -178,9 +175,8 @@ files: | |
| 178 175 | 
             
            - spec/fixtures/zh-CN.yml
         | 
| 179 176 | 
             
            - spec/helpers/locale_helper.rb
         | 
| 180 177 | 
             
            - spec/spec_helper.rb
         | 
| 178 | 
            +
            - spec/yaml-translator/context_spec.rb
         | 
| 181 179 | 
             
            - spec/yaml-translator/locale_spec.rb
         | 
| 182 | 
            -
            - spec/yaml-translator/structure/single_key.rb
         | 
| 183 | 
            -
            - spec/yaml-translator/structure/tree_spec.rb
         | 
| 184 180 | 
             
            - spec/yaml-translator/translator_spec.rb
         | 
| 185 181 | 
             
            - spec/yaml_translator_spec.rb
         | 
| 186 182 | 
             
            - yaml-translator.gemspec
         | 
| @@ -217,8 +213,7 @@ test_files: | |
| 217 213 | 
             
            - spec/fixtures/zh-CN.yml
         | 
| 218 214 | 
             
            - spec/helpers/locale_helper.rb
         | 
| 219 215 | 
             
            - spec/spec_helper.rb
         | 
| 216 | 
            +
            - spec/yaml-translator/context_spec.rb
         | 
| 220 217 | 
             
            - spec/yaml-translator/locale_spec.rb
         | 
| 221 | 
            -
            - spec/yaml-translator/structure/single_key.rb
         | 
| 222 | 
            -
            - spec/yaml-translator/structure/tree_spec.rb
         | 
| 223 218 | 
             
            - spec/yaml-translator/translator_spec.rb
         | 
| 224 219 | 
             
            - spec/yaml_translator_spec.rb
         | 
| @@ -1,27 +0,0 @@ | |
| 1 | 
            -
            module YamlTranslator
         | 
| 2 | 
            -
              module Structure
         | 
| 3 | 
            -
                module SingleKey
         | 
| 4 | 
            -
                  # Covert to a flatten hash
         | 
| 5 | 
            -
                  def to_single_key
         | 
| 6 | 
            -
                    compact_of(self, KeyPath.new)
         | 
| 7 | 
            -
                  end
         | 
| 8 | 
            -
             | 
| 9 | 
            -
                  private
         | 
| 10 | 
            -
             | 
| 11 | 
            -
                  # Covert to a flatten hash
         | 
| 12 | 
            -
                  def compact_of(values={}, path=KeyPath.new)
         | 
| 13 | 
            -
                    result = {}
         | 
| 14 | 
            -
                    values.each_with_index do |(i, v)|
         | 
| 15 | 
            -
                      path.move_to(i)
         | 
| 16 | 
            -
                      if v.is_a?(Hash)
         | 
| 17 | 
            -
                        result.merge!(compact_of(v, path))
         | 
| 18 | 
            -
                      else
         | 
| 19 | 
            -
                        result[path.to_s] = v
         | 
| 20 | 
            -
                      end
         | 
| 21 | 
            -
                      path.leave
         | 
| 22 | 
            -
                    end
         | 
| 23 | 
            -
                    result
         | 
| 24 | 
            -
                  end
         | 
| 25 | 
            -
                end
         | 
| 26 | 
            -
              end
         | 
| 27 | 
            -
            end
         | 
| @@ -1,35 +0,0 @@ | |
| 1 | 
            -
            module YamlTranslator
         | 
| 2 | 
            -
              module Structure
         | 
| 3 | 
            -
                module Tree
         | 
| 4 | 
            -
                  def to_tree
         | 
| 5 | 
            -
                    tree_of(self)
         | 
| 6 | 
            -
                  end
         | 
| 7 | 
            -
             | 
| 8 | 
            -
                  private
         | 
| 9 | 
            -
             | 
| 10 | 
            -
                  # Returning the flattened structure to the tree structure
         | 
| 11 | 
            -
                  #
         | 
| 12 | 
            -
                  # @param [Hash] values flatten Hash
         | 
| 13 | 
            -
                  # @return [Hash] translated hash
         | 
| 14 | 
            -
                  def tree_of(values)
         | 
| 15 | 
            -
                    result = {}
         | 
| 16 | 
            -
                    current = result
         | 
| 17 | 
            -
                    values.each do |k, v|
         | 
| 18 | 
            -
                      keys = k.split('.')
         | 
| 19 | 
            -
                      last_key = keys.pop
         | 
| 20 | 
            -
                      keys.each do |ks|
         | 
| 21 | 
            -
                        current = if current.key?(ks)
         | 
| 22 | 
            -
                                    current[ks]
         | 
| 23 | 
            -
                                  else
         | 
| 24 | 
            -
                                    current[ks] = {}
         | 
| 25 | 
            -
                                    current[ks]
         | 
| 26 | 
            -
                                  end
         | 
| 27 | 
            -
                      end
         | 
| 28 | 
            -
                      current[last_key] = v
         | 
| 29 | 
            -
                      current = result
         | 
| 30 | 
            -
                    end
         | 
| 31 | 
            -
                    result
         | 
| 32 | 
            -
                  end
         | 
| 33 | 
            -
                end
         | 
| 34 | 
            -
              end
         | 
| 35 | 
            -
            end
         |