diff --git a/lib/sof/all.rb b/lib/sof/all.rb index cbdf2ffc..841fa004 100644 --- a/lib/sof/all.rb +++ b/lib/sof/all.rb @@ -5,31 +5,30 @@ require_relative "writer" require_relative "array" require_relative "hash" require_relative "occurence" +require_relative "node" Symbol.class_eval do - def to_sof(io, members) - io.write ":#{to_s}" + def to_sof() + ":#{to_s}" end end TrueClass.class_eval do - def to_sof(io , members) - io.write "true" + def to_sof() + "true" end end FalseClass.class_eval do - def to_sof(io , members) - io.write "false" + def to_sof() + "false" end end String.class_eval do - def to_sof(io, members) - io.write "'" - io.write self - io.write "'" + def to_sof() + "'" + self + "'" end end Fixnum.class_eval do - def to_sof(io , members) - io.write to_s + def to_sof() + to_s end end diff --git a/lib/sof/array.rb b/lib/sof/array.rb index dba030d5..321a517b 100644 --- a/lib/sof/array.rb +++ b/lib/sof/array.rb @@ -1,10 +1,9 @@ Array.class_eval do - def to_sof(io , members , level) - each_with_index do |object , i| - io.write(" " * level) unless i == 0 - io.write("-") - members.output(io , object) - io.write("\n") + def to_sof_node(members , level) + node = Sof::Node.new(nil) + each do |object| + node.add members.to_sof_node( object ) end + node end end diff --git a/lib/sof/hash.rb b/lib/sof/hash.rb index b90d602b..38d329a6 100644 --- a/lib/sof/hash.rb +++ b/lib/sof/hash.rb @@ -1,5 +1,5 @@ Hash.class_eval do - def to_sof(io , members , level) + def to_sof_node(members , level) each_with_index do |pair , i| key , object = pair io.write(" " * level) unless i == 0 diff --git a/lib/sof/node.rb b/lib/sof/node.rb new file mode 100644 index 00000000..4bed1f18 --- /dev/null +++ b/lib/sof/node.rb @@ -0,0 +1,30 @@ +# We transform objects into a tree of nodes + +module Sof + class Node + def initialize head + @head = head + end + attr_accessor :head , :children + def add child + child = Node.new(child) if(child.is_a? String) + @children = [] if(@children.nil?) + @children << child + end + + def out io , level = 0 + io.write head + return unless @children + first = @children[0] + io.write " " + first.out(io , level + 1) + indent = " " * level + @children.each do |child| + next if child == first # done already + io.write indent + io.write "-" + child.out(io , level + 1) + end + end + end +end diff --git a/lib/sof/writer.rb b/lib/sof/writer.rb index 1e1490d4..666eff96 100644 --- a/lib/sof/writer.rb +++ b/lib/sof/writer.rb @@ -6,47 +6,37 @@ module Sof end def write + node = to_sof_node(@members.root) io = StringIO.new - output io , @members.root + node.out( io ) io.string end - def output io , object + def to_sof_node(object) if is_value?(object) - object.to_sof(io , self) - return + return Node.new(object.to_sof()) end occurence = @members.objects[object] raise "no object #{object}" unless occurence - if(object.respond_to? :to_sof) #mainly meant for arrays and hashes - object.to_sof(io , self , occurence.level) + if(object.respond_to? :to_sof_node) #mainly meant for arrays and hashes + object.to_sof_node(self , occurence.level) else - object_sof(object , io , occurence.level) + object_sof_node(object , occurence.level) end end - def object_sof( object , io , level) - io.write object.class.name - io.write "(" + def object_sof_node( object , level) + head = object.class.name + "(" attributes = attributes_for(object) - attributes.each_with_index do |a , i| + immediate , extended = attributes.partition {|a| is_value?(get_value(object , a) ) } + head += immediate.collect {|a| "#{a}: #{get_value(object , a)}"}.join(", ") + ")" + + node = Node.new(head) + extended.each do |a| val = get_value(object , a) - next unless is_value?(val) - io.write( a ) - io.write( ": " ) - output( io , val) - io.write(" ,") unless i == (attributes.length - 1) - end - io.write ")" - attributes.each_with_index do |a , i| - val = get_value(object , a) - next if is_value?(val) - io.write " " * (level+1) - io.write "-" - io.write( a ) - io.write( ": " ) - output( io , val) + node.add to_sof_node(val) end + node end def self.write object