SgfParser 0.9.0 → 0.9.1

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.
data/.document CHANGED
@@ -1,5 +1,5 @@
1
- README.rdoc
2
- lib/**/*.rb
3
- bin/*
4
- features/**/*.feature
5
- LICENSE
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color --format doc
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm 1.9.2@jrun
data/Gemfile ADDED
@@ -0,0 +1,12 @@
1
+ # A sample Gemfile
2
+ source "http://rubygems.org"
3
+
4
+
5
+ group :development do
6
+ gem "jeweler"
7
+ gem "rcov"
8
+ end
9
+
10
+ group :test do
11
+ gem "rspec"
12
+ end
@@ -0,0 +1,27 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ diff-lcs (1.1.2)
5
+ git (1.2.5)
6
+ jeweler (1.6.4)
7
+ bundler (~> 1.0)
8
+ git (>= 1.2.5)
9
+ rake
10
+ rake (0.9.2)
11
+ rcov (0.9.9)
12
+ rspec (2.6.0)
13
+ rspec-core (~> 2.6.0)
14
+ rspec-expectations (~> 2.6.0)
15
+ rspec-mocks (~> 2.6.0)
16
+ rspec-core (2.6.4)
17
+ rspec-expectations (2.6.0)
18
+ diff-lcs (~> 1.1.2)
19
+ rspec-mocks (2.6.0)
20
+
21
+ PLATFORMS
22
+ ruby
23
+
24
+ DEPENDENCIES
25
+ jeweler
26
+ rcov
27
+ rspec
data/Rakefile CHANGED
@@ -18,38 +18,23 @@ rescue LoadError
18
18
  puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
19
19
  end
20
20
 
21
- require 'spec/rake/spectask'
22
- Spec::Rake::SpecTask.new(:spec) do |spec|
23
- spec.libs << 'lib' << 'spec'
24
- spec.spec_files = FileList['spec/**/*_spec.rb']
21
+ require 'rspec/core/rake_task'
22
+ desc 'Default: run specs.'
23
+ task :default => :spec
24
+
25
+ desc "Run specs"
26
+ RSpec::Core::RakeTask.new do |spec|
27
+ spec.pattern = "./spec/**/*_spec.rb"
25
28
  end
26
29
 
27
- Spec::Rake::SpecTask.new(:rcov) do |spec|
28
- spec.libs << 'lib' << 'spec'
30
+ RSpec::Core::RakeTask.new(:coverage) do |spec|
29
31
  spec.pattern = 'spec/**/*_spec.rb'
30
32
  spec.rcov = true
33
+ spec.rcov_opts = ['--exclude', 'spec']
31
34
  end
32
35
 
33
- task :spec => :check_dependencies
34
-
35
- # In case I ever want to go back to cucumber.
36
- #begin
37
- # require 'cucumber/rake/task'
38
- # Cucumber::Rake::Task.new(:features)
39
- #
40
- # task :features => :check_dependencies
41
- #rescue LoadError
42
- # task :features do
43
- # abort "Cucumber is not available. In order to run features, you must: sudo gem install cucumber"
44
- # end
45
- #end
46
-
47
- #task :default => [:spec, :features]
48
-
49
- task :default => [:spec]
50
-
51
- require 'rake/rdoctask'
52
- Rake::RDocTask.new do |rdoc|
36
+ require 'rdoc/task'
37
+ RDoc::Task.new do |rdoc|
53
38
  version = File.exist?('VERSION') ? File.read('VERSION') : ""
54
39
 
55
40
  rdoc.rdoc_dir = 'rdoc'
@@ -1,67 +1,71 @@
1
- # Generated by jeweler
2
- # DO NOT EDIT THIS FILE DIRECTLY
3
- # Instead, edit Jeweler::Tasks in rakefile, and run the gemspec command
4
- # -*- encoding: utf-8 -*-
5
-
6
- Gem::Specification.new do |s|
7
- s.name = %q{SgfParser}
8
- s.version = "0.9.0"
9
-
10
- s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
- s.authors = ["Aldric Giacomoni"]
12
- s.date = %q{2010-04-30}
13
- s.description = %q{SGFParser is a library that parses and saves SGF (Smart Game Format) files.}
14
- s.email = %q{aldric@trevoke.net}
15
- s.extra_rdoc_files = [
16
- "LICENSE",
17
- "README.rdoc"
18
- ]
19
- s.files = [
20
- ".document",
21
- ".gitignore",
22
- "LICENSE",
23
- "README.rdoc",
24
- "Rakefile",
25
- "SgfParser.gemspec",
26
- "VERSION",
27
- "lib/sgf/parser/node.rb",
28
- "lib/sgf/parser/properties.rb",
29
- "lib/sgf/parser/tree.rb",
30
- "lib/sgf/parser/tree_parse.rb",
31
- "lib/sgf/sgf_indent.rb",
32
- "lib/sgf_parser.rb",
33
- "sample_sgf/ff4_ex.sgf",
34
- "sample_sgf/redrose-tartrate.sgf",
35
- "sample_usage/parsing_files.rb",
36
- "spec/node_spec.rb",
37
- "spec/spec.opts",
38
- "spec/spec_helper.rb",
39
- "spec/tree_spec.rb",
40
- "tryme.rb"
41
- ]
42
- s.homepage = %q{http://github.com/Trevoke/SGFParser}
43
- s.rdoc_options = ["--charset=UTF-8"]
44
- s.require_paths = ["lib"]
45
- s.rubygems_version = %q{1.3.6}
46
- s.summary = %q{A library for working with SGF files.}
47
- s.test_files = [
48
- "spec/node_spec.rb",
49
- "spec/spec_helper.rb",
50
- "spec/tree_parser_spec.rb",
51
- "spec/tree_spec.rb"
52
- ]
53
-
54
- if s.respond_to? :specification_version then
55
- current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
56
- s.specification_version = 3
57
-
58
- if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
59
- s.add_development_dependency(%q<rspec>, [">= 1.2.9"])
60
- else
61
- s.add_dependency(%q<rspec>, [">= 1.2.9"])
62
- end
63
- else
64
- s.add_dependency(%q<rspec>, [">= 1.2.9"])
65
- end
66
- end
67
-
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{SgfParser}
8
+ s.version = "0.9.1"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Aldric Giacomoni"]
12
+ s.date = %q{2011-07-29}
13
+ s.description = %q{SGFParser is a library that parses and saves SGF (Smart Game Format) files.}
14
+ s.email = %q{aldric@trevoke.net}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ ".rspec",
22
+ ".rvmrc",
23
+ "Gemfile",
24
+ "Gemfile.lock",
25
+ "LICENSE",
26
+ "README.rdoc",
27
+ "Rakefile",
28
+ "SgfParser.gemspec",
29
+ "VERSION",
30
+ "lib/sgf/parser/node.rb",
31
+ "lib/sgf/parser/properties.rb",
32
+ "lib/sgf/parser/tree.rb",
33
+ "lib/sgf/parser/tree_parse.rb",
34
+ "lib/sgf/sgf_indent.rb",
35
+ "lib/sgf/sgfindent.rb",
36
+ "lib/sgf_parser.rb",
37
+ "sample_sgf/ff4_ex.sgf",
38
+ "sample_sgf/ff4_ex_saved.sgf",
39
+ "sample_sgf/redrose-tartrate.sgf",
40
+ "sample_sgf/simple.sgf",
41
+ "sample_sgf/simple_saved.sgf",
42
+ "sample_usage/parsing_files.rb",
43
+ "spec/node_spec.rb",
44
+ "spec/spec_helper.rb",
45
+ "spec/tree_parser_spec.rb",
46
+ "spec/tree_spec.rb"
47
+ ]
48
+ s.homepage = %q{http://github.com/Trevoke/SGFParser}
49
+ s.require_paths = ["lib"]
50
+ s.rubygems_version = %q{1.6.2}
51
+ s.summary = %q{A library for working with SGF files.}
52
+
53
+ if s.respond_to? :specification_version then
54
+ s.specification_version = 3
55
+
56
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
57
+ s.add_development_dependency(%q<jeweler>, [">= 0"])
58
+ s.add_development_dependency(%q<rcov>, [">= 0"])
59
+ s.add_development_dependency(%q<rspec>, [">= 1.2.9"])
60
+ else
61
+ s.add_dependency(%q<jeweler>, [">= 0"])
62
+ s.add_dependency(%q<rcov>, [">= 0"])
63
+ s.add_dependency(%q<rspec>, [">= 1.2.9"])
64
+ end
65
+ else
66
+ s.add_dependency(%q<jeweler>, [">= 0"])
67
+ s.add_dependency(%q<rcov>, [">= 0"])
68
+ s.add_dependency(%q<rspec>, [">= 1.2.9"])
69
+ end
70
+ end
71
+
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.9.0
1
+ 0.9.1
@@ -1,8 +1,5 @@
1
1
  module SgfParser
2
2
 
3
- # Each part of the SGF Tree is a node. This holds links to the parent node,
4
- # to the next node(s) in the tree, and of course, the properties of said node.
5
- # Accessors : node.parent, node.children, node.properties
6
3
  class Node
7
4
 
8
5
  attr_accessor :parent, :children, :properties
@@ -19,9 +16,6 @@ module SgfParser
19
16
  @properties.merge! args[:properties] if !args[:properties].nil?
20
17
  end
21
18
 
22
- # Adds one child or several children. Can be passed in as a comma-separated
23
- # list or an array of node children. Will raise an error if one of the
24
- # arguments is not of class Node.
25
19
  def add_children *nodes
26
20
  nodes.flatten!
27
21
  raise "Non-node child given!" if nodes.find { |node| node.class != Node }
@@ -30,8 +24,6 @@ module SgfParser
30
24
  @children.concat nodes
31
25
  end
32
26
 
33
- # Adds one or more properties to the node.
34
- # Argument: a hash {'property' => 'value'}
35
27
  def add_properties hash
36
28
  hash.each do |key, value|
37
29
  @properties[key] ||= ""
@@ -39,18 +31,14 @@ module SgfParser
39
31
  end
40
32
  end
41
33
 
42
- # Iterates over each child of the given node
43
- # node.each_child { |child| puts child.properties }
44
34
  def each_child
45
35
  @children.each { |child| yield child }
46
36
  end
47
37
 
48
- # Compares one node's properties to another node's properties
49
38
  def == other_node
50
39
  @properties == other_node.properties
51
40
  end
52
41
 
53
- # Making comments easier to access.
54
42
  def comments
55
43
  @properties["C"]
56
44
  end
@@ -1,19 +1,10 @@
1
1
  module SgfParser
2
2
 
3
- # This is a placeholder for the root of the gametree(s). It's an abstraction,
4
- # but it allows an easy way to save, iterate over, and compare other trees.
5
- # Accessors: tree.root
6
3
  class Tree
7
4
  include Enumerable
8
5
 
9
6
  attr_accessor :root
10
7
 
11
- # Create a new tree. Can also be used to load a tree from either a file or
12
- # a string. Raises an error if both are provided.
13
- # options: \n
14
- # :filename => filename \n
15
- # !!! OR !!! \n
16
- # :string => string \n
17
8
  def initialize args={}
18
9
  @root = Node.new
19
10
  @sgf = ""
@@ -27,10 +18,9 @@ module SgfParser
27
18
  parse unless @sgf.empty?
28
19
  end
29
20
 
30
- # Iterates over the tree, node by node, in preorder fashion.
31
- # Does not support other types of iteration, but may in the future.
32
- # tree.each { |node| puts "I am node. Hear me #{node.properties} !"}
33
21
  def each order=:preorder, &block
22
+ # I know, I know. SGF is only preorder. Well, it's implemented, ain't it?
23
+ # Stop complaining.
34
24
  case order
35
25
  when :preorder
36
26
  preorder @root, &block
@@ -51,10 +41,8 @@ module SgfParser
51
41
  # tree.save :filename => file_name
52
42
  def save args={}
53
43
  raise ArgumentError, "No file name provided" if args[:filename].nil?
54
- # SGF files are trees stored in pre-order traversal.
55
44
  @savable_sgf = "("
56
45
  @root.children.each { |child| write_node child }
57
- # write_node @root
58
46
  @savable_sgf << ")"
59
47
 
60
48
  File.open(args[:filename], 'w') { |f| f << @savable_sgf }
@@ -67,11 +55,12 @@ module SgfParser
67
55
  @savable_sgf << ";"
68
56
  unless node.properties.empty?
69
57
  properties = ""
70
- node.properties.each do |k, v|
71
- v_escaped = v.gsub("]", "\\]")
72
- properties += "#{k.to_s}[#{v_escaped}]"
58
+ node.properties.each do |identity, property|
59
+ new_property = property[1...-1]
60
+ new_property.gsub!("]", "\\]") if identity == "C"
61
+ properties += "#{identity.to_s}[#{new_property}]"
73
62
  end
74
- @savable_sgf << "#{properties}"
63
+ @savable_sgf << properties
75
64
  end
76
65
 
77
66
  case node.children.size
@@ -104,13 +93,13 @@ module SgfParser
104
93
  preorder(child, &block)
105
94
  end
106
95
  end
107
- end # preorder
96
+ end
108
97
 
109
98
  def method_missing method_name, *args
110
99
  output = @root.children[0].properties[method_name]
111
100
  super(method_name, args) if output.nil?
112
101
  output
113
- end # method_missing
102
+ end
114
103
 
115
104
  end
116
105
 
@@ -3,9 +3,8 @@ require 'stringio'
3
3
  module SgfParser
4
4
  class Tree
5
5
 
6
- private
6
+ #private
7
7
 
8
- # Creates a tree (truly, a linked list) from @sgf.
9
8
  def parse
10
9
  while char = next_character
11
10
  case char
@@ -65,14 +64,29 @@ module SgfParser
65
64
 
66
65
  def get_property
67
66
  buffer = ""
68
- while true
69
- next_bit = @stream.sysread(1)
70
- break if next_bit == "]"
71
- next_bit << @stream.sysread(1) if next_bit == "\\"
72
- next_bit = "]" if next_bit == "\\]"
73
- buffer << next_bit
67
+ while char = next_character
68
+ case char
69
+ when "]" then break unless multiple_properties?
70
+ when "\\" then
71
+ char << next_character
72
+ char = "]" if char == "\\]"
73
+ end
74
+
75
+ buffer << char
76
+ end
77
+ "[#{buffer}]"
78
+ end
79
+
80
+ def multiple_properties?
81
+ multiple_properties = false
82
+ if char = next_character
83
+ char = next_character if char == "\n"
84
+ if char == "["
85
+ multiple_properties = true
86
+ end
87
+ @stream.pos -= 1
88
+ multiple_properties
74
89
  end
75
- buffer
76
90
  end
77
91
 
78
92
  def store_character(char)
@@ -0,0 +1,118 @@
1
+ module SgfParser
2
+
3
+ # This indents an SGF file to make it more readable. It outputs to the screen
4
+ # by default, but can be given a file as output.
5
+ # Usage: SgfParser::Indenter.new infile, outfile
6
+ class Indenter
7
+
8
+ def initialize file, out=$stdout
9
+ sgf = ""
10
+ File.open(file) { |f| sgf = f.read }
11
+ @new_string = ""
12
+ sgf.gsub! "\\\\n\\\\r", ""
13
+ sgf.gsub! "\\\\r\\\\n", ""
14
+ sgf.gsub! "\\\\r", ""
15
+ sgf.gsub! "\\\\n", ""
16
+ #sgf.gsub! "\n", ""
17
+
18
+ end_of_a_series = false
19
+ identprop = false # We are not in the middle of an identprop value.
20
+ # An identprop is an identity property - a value.
21
+
22
+ sgf_array = sgf.split(//)
23
+ iterator = 0
24
+ array_length = sgf_array.size
25
+ indent = 0
26
+
27
+ while iterator < array_length - 1
28
+ char = sgf_array[iterator]
29
+
30
+ case char
31
+ when '(' # Opening a new branch
32
+ if !identprop
33
+ @new_string << "\n"
34
+ indent += 2
35
+ #tabulate indent
36
+ @new_string << " " * indent
37
+ end
38
+ @new_string << char
39
+
40
+ when ')' # Closing a branch
41
+ @new_string << char
42
+ if !identprop
43
+ @new_string << "\n"
44
+ indent -= 2
45
+ @new_string << " " * indent
46
+ #tabulate indent
47
+ end
48
+
49
+ when ';' # Opening a new node
50
+ if !identprop
51
+ @new_string << "\n"
52
+ @new_string << " " * indent
53
+ #tabulate indent
54
+ end
55
+ @new_string << char
56
+
57
+ when '[' # Open comment?
58
+ if !identprop #If we're not inside a comment, then now we are.
59
+ identprop = true
60
+ end_of_a_series = false
61
+ end
62
+ @new_string << char
63
+
64
+ when ']' # Close comment
65
+ end_of_a_series = true # Maybe end of a series of comments.
66
+ identprop = false # That's our cue to close a comment.
67
+ @new_string << char
68
+
69
+ when "\\" # If we're inside a comment, then maybe we're about to escape a ].
70
+ # This is the whole reason we need this ugly charade of a loop.
71
+ if identprop
72
+ if sgf_array[iterator + 1] == "]"
73
+ @new_string << "\\]"
74
+ iterator += 1
75
+ else
76
+ @new_string << "\\"
77
+ end
78
+ else
79
+ #This should never happen - a backslash outside a comment ?!
80
+ #But let's not have it be told that I'm not prepared.
81
+ @new_string << "\\"
82
+ end
83
+
84
+ when "\n"
85
+ @new_string << "\n"
86
+ @new_string << " " * indent
87
+ #tabulate indent
88
+
89
+ else
90
+ # Well, I guess it's "just" a character after all.
91
+ if end_of_a_series
92
+ end_of_a_series = false
93
+ end
94
+ @new_string << char
95
+ end
96
+
97
+ iterator += 1
98
+ end
99
+
100
+ if out == $stdout
101
+ $stdout << @new_string
102
+ else
103
+ File.open(out, 'w') { |file| file << @new_string }
104
+ end
105
+
106
+ end
107
+
108
+ private
109
+
110
+ def tabulate indent
111
+ indent.times { print " " }
112
+ end
113
+ end
114
+ end
115
+
116
+
117
+
118
+
@@ -0,0 +1,45 @@
1
+ (;FF[4]AP[Primiview:3.1]GM[1]SZ[19]GN[Gametree 1: properties]US[Arno Hollosi](;B[pd]N[Moves, comments, annotations]C[Nodename set to: "Moves, comments, annotations"];W[dp]GW[1]C[Marked as "Good for White"];B[pp]GB[2]C[Marked as "Very good for Black"];W[dc]GW[2]C[Marked as "Very good for White"];B[pj]DM[1]C[Marked as "Even position"];W[ci]UC[1]C[Marked as "Unclear position"];B[jd]TE[1]C[Marked as "Tesuji" or "Good move"];W[jp]BM[2]C[Marked as "Very bad move"];B[gd]DO[]C[Marked as "Doubtful move"];W[de]IT[]C[Marked as "Interesting move"];B[jj];C[White "Pass" move]W[];)(;AB[dd][de][df][dg][do:gq] AW[jd][je][jf][jg][kn:lq][pn:pq]N[Setup]C[Black & white stones at the top are added as single stones.
2
+
3
+ Black & white stones at the bottom are added using compressed point lists.];AE[ep][fp][kn][lo][lq][pn:pq]C[AddEmpty
4
+
5
+ Black stones & stones of left white group are erased in FF[3\] way.
6
+
7
+ White stones at bottom right were erased using compressed point list.];AB[pd]AW[pp]PL[B]C[Added two stones.
8
+
9
+ Node marked with "Black to play".];)(;AB[dd][de][df][dg][dh][di][dj][nj][ni][nh][nf][ne][nd][ij][ii][ih][hq][gq][fq][eq][dr][ds][dq][dp][cp][bp][ap][iq][ir][is][bo][bn][an][ms][mr]AW[pd][pe][pf][pg][ph][pi][pj][fd][fe][ff][fh][fi][fj][kh][ki][kj][os][or][oq][op][pp][qp][rp][sp][ro][rn][sn][nq][mq][lq][kq][kr][ks][fs][gs][gr][er]N[Markup]C[Position set up without compressed point lists.];TR[dd][de][df][ed][ee][ef][fd:ff] MA[dh][di][dj][ej][ei][eh][fh:fj] CR[nd][ne][nf][od][oe][of][pd:pf] SQ[nh][ni][nj][oh][oi][oj][ph:pj] SL[ih][ii][ij][jj][ji][jh][kh:kj] TW[pq:ss][so][lr:ns] TB[aq:cs][er:hs][ao]C[Markup at top partially using compressed point lists (for markup on white stones); listed clockwise, starting at upper left:
10
+ - TR (triangle)
11
+ - CR (circle)
12
+ - SQ (square)
13
+ - SL (selected points)
14
+ - MA ('X')
15
+
16
+ Markup at bottom: black & white territory (using compressed point lists)];LB[dc:1][fc:2][nc:3][pc:4][dj:a][fj:b][nj:c][pj:d][gs:ABCDEFGH][gr:ABCDEFG][gq:ABCDEF][gp:ABCDE][go:ABCD][gn:ABC][gm:AB][mm:12][mn:123][mo:1234][mp:12345][mq:123456][mr:1234567][ms:12345678]C[Label (LB property)
17
+
18
+ Top: 8 single char labels (1-4, a-d)
19
+
20
+ Bottom: Labels up to 8 char length.];)(;B[qd]N[Style & text type]C[There are hard linebreaks & soft linebreaks.
21
+ Soft linebreaks are linebreaks preceeded by '\\' like this one >o\
22
+ k<. Hard line breaks are all other linebreaks.
23
+ Soft linebreaks are converted to >nothing<, i.e. removed.
24
+
25
+ Note that linebreaks are coded differently on different systems.
26
+
27
+ Examples (>ok< shouldn't be split):
28
+
29
+ linebreak 1 "": >o\
30
+ k<
31
+ linebreak 2 "": >o\
32
+
33
+ linebreak 3 "": >o\
34
+ k<
35
+ linebreak 4 "": >o\
36
+ Black stones left (in this byo-yomi period): 10];W[qq]WL[200]OW[2]C[White time left: 200 sec
37
+ White stones left: 2];B[sr]BL[87.00]OB[9]C[Black time left: 87 sec
38
+ Black stones left: 9];W[qs]WL[13.20]OW[1]C[White time left: 13.2 sec
39
+ White stones left: 1];B[rs]C[One white stone at s2 captured];W[ps];B[pr];W[or]MN[2]C[Set move number to 2];B[os]C[Two white stones captured
40
+ (at q1 & r1)];MN[112]W[pq]C[Set move number to 112];B[sq];W[rp];B[ps];W[ns];B[ss];W[nr];B[rr];W[sp];);FF[4]AP[Primiview:3.1]GM[1]SZ[19]C[Gametree 2: game-info
41
+
42
+ Game-info properties are usually stored in the root node.
43
+ If games are merged into a single game-tree, they are stored in the node\
44
+ where the game first becomes distinguishable from all other games in\
45
+ the tree.];B[pd](;)(;)(;W[ep];B[pp](;)(;))
@@ -0,0 +1,11 @@
1
+ (;GM[1]FF[4]CA[UTF-8]
2
+ SZ[19]RU[Japanese]KM[0.50]TM[1290]OT[3x30 byo-yomi]
3
+ PB[tartrate]PW[redrose]BR[7d]WR[1p]DT[2003-06-18]PC[The Kiseido Go Server (KGS) at http://kgs.kiseido.com/]C[tartrate [7d?\]: hi
4
+ tartrate [7d?\]: thx
5
+ ]RE[B+Resign]
6
+ ;B[jj]BL[1280.503]CR[jj]C[redrose [1p\]: hi
7
+ Jerk [7d?\]: wow
8
+ Anark [11k\]: game of the day :)
9
+ Jerk [7d?\]: really big match
10
+ ]
11
+ ;W[ih]WL[1277.190]CR[ih];AB[aa][bb][cc])
@@ -0,0 +1,7 @@
1
+ (;GM[1]FF[4]CA[UTF-8]
2
+ tartrate [7d?\]: thx
3
+ ]RE[B+Resign];B[jj]BL[1280.503]CR[jj]C[redrose [1p\]: hi
4
+ Jerk [7d?\]: wow
5
+ Anark [11k\]: game of the day :)
6
+ Jerk [7d?\]: really big match
7
+ ];W[ih]WL[1277.190]CR[ih];))
@@ -1,9 +1,6 @@
1
1
  $LOAD_PATH.unshift(File.dirname(__FILE__))
2
2
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
3
  require 'sgf_parser'
4
- require 'spec'
5
- require 'spec/autorun'
4
+ require 'rspec'
5
+ require 'rspec/autorun'
6
6
 
7
- Spec::Runner.configure do |config|
8
-
9
- end
@@ -6,8 +6,19 @@ describe "SgfParser::Tree.parse" do
6
6
  @tree = SgfParser::Tree.new :filename => 'sample_sgf/ff4_ex.sgf'
7
7
  end
8
8
 
9
- it "should return true" do
10
- true
9
+ it "should have FF in the first node" do
10
+ @tree.root.children[0].properties.keys.should include("FF")
11
+ end
12
+
13
+ it "should give an error if FF is missing from the first node" do
14
+ pending "To be coded later"
15
+ end
16
+
17
+ it "should parse properly the AW property" do
18
+ input = StringIO.new "dd][de][ef]"
19
+ tree = SgfParser::Tree.new
20
+ tree.instance_variable_set "@stream", input
21
+ tree.get_property.should == "[dd][de][ef]"
11
22
  end
12
23
 
13
24
  end
@@ -3,20 +3,39 @@ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
3
3
  describe "SgfParser::Tree" do
4
4
 
5
5
  before :each do
6
- @tree = SgfParser::Tree.new :filename => 'sample_sgf/ff4_ex.sgf'
6
+
7
7
  end
8
8
 
9
9
  it "should parse properly" do
10
- @tree.class.should == SgfParser::Tree
11
- @tree.root.children.size.should == 2
12
- @tree.root.children[0].children.size.should == 5
10
+ tree = SgfParser::Tree.new :filename => 'sample_sgf/ff4_ex.sgf'
11
+ tree.class.should == SgfParser::Tree
12
+ tree.root.children.size.should == 2
13
+ tree.root.children[0].children.size.should == 5
14
+ end
15
+
16
+ it "should save a simple tree properly" do
17
+ tree = SgfParser::Tree.new :filename => 'sample_sgf/simple.sgf'
18
+ new = 'sample_sgf/simple_saved.sgf'
19
+ tree.save :filename => new
20
+ tree2 = SgfParser::Tree.new :filename => new
21
+ tree.should == tree2
13
22
  end
14
23
 
15
- it "should save properly" do
16
- @new = 'sample_sgf/ff4_ex_saved.sgf'
17
- @tree.save :filename => @new
18
- @tree2 = SgfParser::Tree.new :filename => @new
19
- @tree2.should == @tree
24
+ it "should save the sample SGF properly" do
25
+ tree = SgfParser::Tree.new :filename => 'sample_sgf/ff4_ex.sgf'
26
+ new = 'sample_sgf/ff4_ex_saved.sgf'
27
+ tree.save :filename => new
28
+ tree2 = SgfParser::Tree.new :filename => new
29
+ tree_children = []
30
+ tree2_children = []
31
+ tree.each { |node| tree_children << node }
32
+ tree2.each { |node| tree2_children << node }
33
+ tree_children.size.should == tree2_children.size
34
+ tree_children.each_with_index do |node, index|
35
+ node.properties.should == tree2_children[index].properties
36
+ end
37
+ tree_children.should == tree2_children
38
+ tree2.should == tree
20
39
  end
21
40
 
22
41
  end
metadata CHANGED
@@ -1,12 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: SgfParser
3
3
  version: !ruby/object:Gem::Version
4
- prerelease: false
4
+ hash: 57
5
+ prerelease:
5
6
  segments:
6
7
  - 0
7
8
  - 9
8
- - 0
9
- version: 0.9.0
9
+ - 1
10
+ version: 0.9.1
10
11
  platform: ruby
11
12
  authors:
12
13
  - Aldric Giacomoni
@@ -14,23 +15,53 @@ autorequire:
14
15
  bindir: bin
15
16
  cert_chain: []
16
17
 
17
- date: 2010-04-30 00:00:00 -04:00
18
+ date: 2011-07-29 00:00:00 -04:00
18
19
  default_executable:
19
20
  dependencies:
20
21
  - !ruby/object:Gem::Dependency
21
- name: rspec
22
- prerelease: false
22
+ type: :development
23
23
  requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ hash: 3
29
+ segments:
30
+ - 0
31
+ version: "0"
32
+ name: jeweler
33
+ version_requirements: *id001
34
+ prerelease: false
35
+ - !ruby/object:Gem::Dependency
36
+ type: :development
37
+ requirement: &id002 !ruby/object:Gem::Requirement
38
+ none: false
24
39
  requirements:
25
40
  - - ">="
26
41
  - !ruby/object:Gem::Version
42
+ hash: 3
43
+ segments:
44
+ - 0
45
+ version: "0"
46
+ name: rcov
47
+ version_requirements: *id002
48
+ prerelease: false
49
+ - !ruby/object:Gem::Dependency
50
+ type: :development
51
+ requirement: &id003 !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ hash: 13
27
57
  segments:
28
58
  - 1
29
59
  - 2
30
60
  - 9
31
61
  version: 1.2.9
32
- type: :development
33
- version_requirements: *id001
62
+ name: rspec
63
+ version_requirements: *id003
64
+ prerelease: false
34
65
  description: SGFParser is a library that parses and saves SGF (Smart Game Format) files.
35
66
  email: aldric@trevoke.net
36
67
  executables: []
@@ -42,7 +73,10 @@ extra_rdoc_files:
42
73
  - README.rdoc
43
74
  files:
44
75
  - .document
45
- - .gitignore
76
+ - .rspec
77
+ - .rvmrc
78
+ - Gemfile
79
+ - Gemfile.lock
46
80
  - LICENSE
47
81
  - README.rdoc
48
82
  - Rakefile
@@ -53,47 +87,51 @@ files:
53
87
  - lib/sgf/parser/tree.rb
54
88
  - lib/sgf/parser/tree_parse.rb
55
89
  - lib/sgf/sgf_indent.rb
90
+ - lib/sgf/sgfindent.rb
56
91
  - lib/sgf_parser.rb
57
92
  - sample_sgf/ff4_ex.sgf
93
+ - sample_sgf/ff4_ex_saved.sgf
58
94
  - sample_sgf/redrose-tartrate.sgf
95
+ - sample_sgf/simple.sgf
96
+ - sample_sgf/simple_saved.sgf
59
97
  - sample_usage/parsing_files.rb
60
98
  - spec/node_spec.rb
61
- - spec/spec.opts
62
99
  - spec/spec_helper.rb
100
+ - spec/tree_parser_spec.rb
63
101
  - spec/tree_spec.rb
64
- - tryme.rb
65
102
  has_rdoc: true
66
103
  homepage: http://github.com/Trevoke/SGFParser
67
104
  licenses: []
68
105
 
69
106
  post_install_message:
70
- rdoc_options:
71
- - --charset=UTF-8
107
+ rdoc_options: []
108
+
72
109
  require_paths:
73
110
  - lib
74
111
  required_ruby_version: !ruby/object:Gem::Requirement
112
+ none: false
75
113
  requirements:
76
114
  - - ">="
77
115
  - !ruby/object:Gem::Version
116
+ hash: 3
78
117
  segments:
79
118
  - 0
80
119
  version: "0"
81
120
  required_rubygems_version: !ruby/object:Gem::Requirement
121
+ none: false
82
122
  requirements:
83
123
  - - ">="
84
124
  - !ruby/object:Gem::Version
125
+ hash: 3
85
126
  segments:
86
127
  - 0
87
128
  version: "0"
88
129
  requirements: []
89
130
 
90
131
  rubyforge_project:
91
- rubygems_version: 1.3.6
132
+ rubygems_version: 1.6.2
92
133
  signing_key:
93
134
  specification_version: 3
94
135
  summary: A library for working with SGF files.
95
- test_files:
96
- - spec/node_spec.rb
97
- - spec/spec_helper.rb
98
- - spec/tree_parser_spec.rb
99
- - spec/tree_spec.rb
136
+ test_files: []
137
+
data/.gitignore DELETED
@@ -1,25 +0,0 @@
1
- ## MAC OS
2
- .DS_Store
3
-
4
- ## TEXTMATE
5
- *.tmproj
6
- tmtags
7
-
8
- ## EMACS
9
- *~
10
- \#*
11
- .\#*
12
-
13
- ## VIM
14
- *.swp
15
-
16
- ## PROJECT::GENERAL
17
- coverage
18
- rdoc
19
- pkg
20
-
21
- ## PROJECT::SPECIFIC
22
-
23
-
24
- ## Rubymine
25
- .idea/*
@@ -1 +0,0 @@
1
- --color
data/tryme.rb DELETED
@@ -1,3 +0,0 @@
1
- require 'irb/completion'
2
- require 'lib/sgf_parser'
3
- sgf = SgfParser::Tree.new :filename => 'sample_sgf/ff4_ex.sgf'