1+ require 'node'
2+ #TODO It's still just a damn list! Have to make it into a tree!
3+ class SGFTree
4+
5+ attr_accessor :root , :sgf
6+
7+ def initialize string = ""
8+ @root = SGFNode . new :depth => -1 , :previous => nil
9+ @sgf = ""
10+ File . open ( string , 'r' ) { |f | @sgf = f . read }
11+ parse unless @sgf . empty?
12+ end
13+
14+ def each
15+ node_list = [ ]
16+ end
17+
18+ private
19+
20+ def parse
21+ # Getting rid of newlines.
22+ @sgf . gsub! "\\ \\ n\\ \\ r" , ""
23+ @sgf . gsub! "\\ \\ r\\ \\ n" , ""
24+ @sgf . gsub! "\\ \\ r" , ""
25+ @sgf . gsub! "\\ \\ n" , ""
26+ @sgf . gsub! "\n " , " "
27+ #previous = @root # Initialize : first is the root, then...
28+ current = @root
29+ depth = 0 # Clearly the next node's depth is 0...
30+ identprop = false # We are not in the middle of an identprop value.
31+ content = Hash . new # Hash holding all the properties
32+ param , property = "" , "" # Variables holding the properties
33+ end_of_a_series = false # To keep track of params with multiple properties
34+
35+ # Simplest way is probably to iterate through every character, and use
36+ # a case scenario
37+ @sgf . each_char do |char |
38+ case char
39+ when '(' # Opening a new branch
40+ identprop ? ( property += char ) : ( depth += 1 )
41+
42+ when ')' # Closing a branch
43+
44+ if identprop
45+ property += char
46+ else
47+ # back to correct node. Should just be one.
48+ #depth -= 1 # Wrong thinking? Have it removed?
49+ current = current . previous until current . depth == depth
50+ end
51+
52+ when ';' # Opening a new node
53+ if identprop
54+ property += char
55+ else
56+ # Make the current node the old node, make new node, store data
57+ previous = current
58+ current = SGFNode . new :previous => previous , :depth => depth
59+ previous . add_properties content
60+ previous . add_next current
61+ param , property = "" , ""
62+ content . clear
63+ end
64+
65+ when '[' # Open comment?
66+ if identprop
67+ property += char
68+ else # If we're not inside a comment, then now we are.
69+ identprop = true
70+ end_of_a_series = false
71+ end
72+
73+ when ']' # Close comment
74+ end_of_a_series = true # Maybe end of a series of comments.
75+ identprop = false # That's our cue to close a comment.
76+ content [ param ] ||= [ ]
77+ content [ param ] << property
78+ property = ""
79+ when '\]'
80+ identprop ? ( property += char ) : param += char
81+ when ' '
82+ identprop ? ( property += char ) : next
83+
84+ else
85+ # Well, I guess it's "just" a character after all.
86+ if end_of_a_series
87+ end_of_a_series = false
88+ param , property = "" , ""
89+ end
90+ identprop ? ( property += char ) : param += char
91+ end
92+
93+ end
94+ end
95+
96+ def method_missing method_name , *args
97+ output = @root . next [ 0 ] . properties [ method_name ]
98+ super if output . nil?
99+ output
100+ end
101+
102+ end
0 commit comments