Sha256: 1dc24522c0d6b7ddac12316b00f2a0044c7502da82f4545f6312b119b822f7c2

Contents?: true

Size: 1.97 KB

Versions: 5

Compression:

Stored size: 1.97 KB

Contents

module Nanaimo
  # Transforms native ruby objects or Plist objects into their ASCII Plist
  # string representation, formatted as Xcode writes Xcode projects.
  #
  class XcodeProjectWriter < Writer
    ISA = String.new('isa', '')
    private_constant :ISA

    def initialize(*)
      super
      @objects_section = false
    end

    private

    def write_dictionary(object)
      n = newlines
      @newlines = false if flat_dictionary?(object)
      return super(sort_dictionary(object)) unless @objects_section
      @objects_section = false
      write_dictionary_start
      value = value_for(object)
      objects_by_isa = value.group_by { |_k, v| isa_for(v) }
      objects_by_isa.each do |isa, kvs|
        write_newline
        output << "/* Begin #{isa} section */"
        write_newline
        sort_dictionary(kvs).each do |k, v|
          write_dictionary_key_value_pair(k, v)
        end
        output << "/* End #{isa} section */"
        write_newline
      end
      write_dictionary_end
    ensure
      @newlines = n
    end

    def write_dictionary_key_value_pair(k, v)
      @objects_section = true if value_for(k) == 'objects'
      super
    end

    def sort_dictionary(dictionary)
      hash = value_for(dictionary)
      hash.to_a.sort do |(k1, v1), (k2, v2)|
        v2_isa = isa_for(v2)
        v1_isa = v2_isa && isa_for(v1)
        comp = v1_isa <=> v2_isa
        next comp if !comp.zero? && v1_isa

        key1 = value_for(k1)
        key2 = value_for(k2)
        next -1 if key1 == 'isa'
        next 1 if key2 == 'isa'
        key1 <=> key2
      end
    end

    def isa_for(dictionary)
      dictionary = value_for(dictionary)
      return unless dictionary.is_a?(Hash)
      isa = dictionary.values_at('isa', ISA).map(&method(:value_for)).compact.first
      isa && value_for(isa)
    end

    def flat_dictionary?(dictionary)
      case isa_for(dictionary)
      when 'PBXBuildFile', 'PBXFileReference'
        true
      else
        false
      end
    end
  end
end

Version data entries

5 entries across 5 versions & 1 rubygems

Version Path
nanaimo-0.1.4 lib/nanaimo/xcode_project_writer.rb
nanaimo-0.1.3 lib/nanaimo/xcode_project_writer.rb
nanaimo-0.1.2 lib/nanaimo/xcode_project_writer.rb
nanaimo-0.1.1 lib/nanaimo/xcode_project_writer.rb
nanaimo-0.1.0 lib/nanaimo/xcode_project_writer.rb