theoros-rubysgf 0.0.2
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/LICENSE.txt +19 -0
- data/lib/rubysgf.rb +76 -0
- data/lib/sgf/compressed_list.rb +30 -0
- data/lib/sgf/coordinates.rb +74 -0
- data/lib/sgf/errors.rb +14 -0
- data/lib/sgf/node.rb +68 -0
- data/lib/sgf/property.rb +102 -0
- data/lib/sgf/record.rb +66 -0
- data/rubysgf.gemspec +25 -0
- metadata +61 -0
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
Copyright (c) 2008 Adam Prescott <disaffect@gmail.com>
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
5
|
+
in the Software without restriction, including without limitation the rights
|
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
8
|
+
furnished to do so, subject to the following conditions:
|
|
9
|
+
|
|
10
|
+
The above copyright notice and this permission notice shall be included in
|
|
11
|
+
all copies or substantial portions of the Software.
|
|
12
|
+
|
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
19
|
+
THE SOFTWARE.
|
data/lib/rubysgf.rb
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
#--
|
|
2
|
+
# Copyright (c) 2008 Adam Prescott
|
|
3
|
+
# licensed as specified under LICENSE.txt
|
|
4
|
+
#++
|
|
5
|
+
|
|
6
|
+
$:.unshift(File.dirname(__FILE__)) unless
|
|
7
|
+
$:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
|
|
8
|
+
|
|
9
|
+
require "strscan"
|
|
10
|
+
require "sgf/errors"
|
|
11
|
+
require "sgf/coordinates"
|
|
12
|
+
require "sgf/compressed_list"
|
|
13
|
+
require "sgf/property"
|
|
14
|
+
require "sgf/node"
|
|
15
|
+
require "sgf/record"
|
|
16
|
+
|
|
17
|
+
module RubySGF
|
|
18
|
+
VERSION = "0.0.2"
|
|
19
|
+
|
|
20
|
+
module SGF # Go-specific under FF[4]
|
|
21
|
+
|
|
22
|
+
ALL_PROPERTY_NAMES = %w{ B KO MN W AB AE AW PL C DM GB GW HO N UC V BM DO IT TE AR CR DD LB LN MA SL SQ TR AP CA FF GM ST SZ AN BR BT CP DT EV GN GC ON OT PB PC PW RE RO RU SO TM US WR WT BL OB OW WL FG PM VW HA KM TB TW }
|
|
23
|
+
|
|
24
|
+
# properties which have values which are coordinates and implemented by this program
|
|
25
|
+
COORDINATE_PROPERTIES = %w{ B W AB AW AE CR MA SQ TR TW TB }
|
|
26
|
+
|
|
27
|
+
# the properties going to be implemented by this program
|
|
28
|
+
PROPERTY_NAMES_HASH = {
|
|
29
|
+
:black_move => "B",
|
|
30
|
+
:white_move => "W",
|
|
31
|
+
:black_stones => "AB",
|
|
32
|
+
:white_stones => "AW",
|
|
33
|
+
:neutral_points => "AE",
|
|
34
|
+
:comment => "C",
|
|
35
|
+
:node_name => "N",
|
|
36
|
+
:circled_points => "CR",
|
|
37
|
+
:label => "LB",
|
|
38
|
+
:marked_x => "MA",
|
|
39
|
+
:squared_points => "SQ",
|
|
40
|
+
:triangled_points => "TR",
|
|
41
|
+
:application => "AP",
|
|
42
|
+
:character_set => "CA",
|
|
43
|
+
:file_format => "FF",
|
|
44
|
+
:game_type => "GM",
|
|
45
|
+
:board_size => "SZ",
|
|
46
|
+
:annotator => "AN",
|
|
47
|
+
:black_rank => "BR",
|
|
48
|
+
:copyright_info => "CP",
|
|
49
|
+
:game_date => "DT",
|
|
50
|
+
:game_name => "GN",
|
|
51
|
+
:overtime => "OT",
|
|
52
|
+
:black_player => "PB",
|
|
53
|
+
:game_location => "PC",
|
|
54
|
+
:white_player => "PW",
|
|
55
|
+
:game_result => "RE",
|
|
56
|
+
:ruleset => "RU",
|
|
57
|
+
:source => "SO",
|
|
58
|
+
:time_limits => "TM",
|
|
59
|
+
:white_rank => "WR",
|
|
60
|
+
:black_time_left => "BL",
|
|
61
|
+
:black_overtime => "OB",
|
|
62
|
+
:white_time_left => "WL",
|
|
63
|
+
:white_overtime => "OW",
|
|
64
|
+
:handicap => "HA",
|
|
65
|
+
:komi => "KM",
|
|
66
|
+
:white_territory => "TW",
|
|
67
|
+
:black_territory => "TB",
|
|
68
|
+
:markup_style => "ST"
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
# implemented by this program
|
|
72
|
+
PROPERTY_NAMES = PROPERTY_NAMES_HASH.values
|
|
73
|
+
|
|
74
|
+
NOT_IMPLEMENTED_PROPERTY_NAMES = ALL_PROPERTY_NAMES - PROPERTY_NAMES
|
|
75
|
+
end # SGF
|
|
76
|
+
end # RSGF
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
#--
|
|
2
|
+
# Copyright (c) 2008 Adam Prescott
|
|
3
|
+
# licensed as specified under LICENSE.txt
|
|
4
|
+
#++
|
|
5
|
+
|
|
6
|
+
module RubySGF
|
|
7
|
+
module SGF
|
|
8
|
+
class CompressedList
|
|
9
|
+
attr_reader :ulx, :uly, :lrx, :lry
|
|
10
|
+
def initialize(upper_left_x, upper_left_y, lower_right_x, lower_right_y)
|
|
11
|
+
@ulx, @uly, @lrx, @lry = upper_left_x, upper_left_y, lower_right_x, lower_right_y
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# expand compressed list to array
|
|
15
|
+
def to_a
|
|
16
|
+
smallx, bigx = [ulx, lrx].sort.map { |i| Coordinates::HORIZONTAL.index(i) }
|
|
17
|
+
xgap = bigx - smallx
|
|
18
|
+
smally, bigy = [uly, lry].sort.map { |i| Coordinates::VERTICAL.index(i) }
|
|
19
|
+
ygap = bigy - smally
|
|
20
|
+
coord_list = []
|
|
21
|
+
Coordinates::VERTICAL[smally..bigy].each do |y|
|
|
22
|
+
Coordinates::HORIZONTAL[smallx..bigx].each do |x|
|
|
23
|
+
coord_list << [x,y]
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
coord_list.sort
|
|
27
|
+
end
|
|
28
|
+
end # compressedlist
|
|
29
|
+
end # sgf
|
|
30
|
+
end # rsgf
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
#--
|
|
2
|
+
# Copyright (c) 2008 Adam Prescott
|
|
3
|
+
# licensed as specified under LICENSE.txt
|
|
4
|
+
#++
|
|
5
|
+
|
|
6
|
+
module RubySGF
|
|
7
|
+
module SGF
|
|
8
|
+
class Coordinates
|
|
9
|
+
VERTICAL = HORIZONTAL = [*"a".."z"] + [*"A".."Z"]
|
|
10
|
+
|
|
11
|
+
attr_reader :x, :y
|
|
12
|
+
def initialize(x, y)
|
|
13
|
+
@x = x
|
|
14
|
+
@y = y
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def ==(second_coordinates)
|
|
18
|
+
@x == second_coordinates.x && @y == second_coordinates.y
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def neighbours(size)
|
|
22
|
+
[up, right, down, left].compact.map do |c|
|
|
23
|
+
c.inside?(size) ? c : nil
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def inside?(size)
|
|
28
|
+
vert = VERTICAL[0,size]
|
|
29
|
+
horiz = HORIZONTAL[0,size]
|
|
30
|
+
horiz.include?(@x) && vert.include?(@y)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def outside?(size)
|
|
34
|
+
!inside?(size)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def up
|
|
38
|
+
idx = VERTICAL.index(y) - 1
|
|
39
|
+
return nil unless idx >= 0
|
|
40
|
+
new_y = VERTICAL[idx]
|
|
41
|
+
return nil unless new_y
|
|
42
|
+
Coordinates.new(x, new_y)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def right
|
|
46
|
+
idx = HORIZONTAL.index(x) + 1
|
|
47
|
+
return nil unless idx >= 0
|
|
48
|
+
new_x = HORIZONTAL[idx]
|
|
49
|
+
return nil unless new_x
|
|
50
|
+
Coordinates.new(new_x, y)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def down
|
|
54
|
+
idx = VERTICAL.index(y) + 1
|
|
55
|
+
return nil unless idx >= 0
|
|
56
|
+
new_y = VERTICAL[idx]
|
|
57
|
+
return nil unless new_y
|
|
58
|
+
Coordinates.new(x, new_y)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def left
|
|
62
|
+
idx = HORIZONTAL.index(x) - 1
|
|
63
|
+
return nil unless idx >= 0
|
|
64
|
+
new_x = HORIZONTAL[idx]
|
|
65
|
+
return nil unless new_x
|
|
66
|
+
Coordinates.new(new_x, y)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def to_s
|
|
70
|
+
@x + @y
|
|
71
|
+
end
|
|
72
|
+
end # coordinates
|
|
73
|
+
end # SGF
|
|
74
|
+
end # RSGF
|
data/lib/sgf/errors.rb
ADDED
data/lib/sgf/node.rb
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
#--
|
|
2
|
+
# Copyright (c) 2008 Adam Prescott
|
|
3
|
+
# licensed as specified under LICENSE.txt
|
|
4
|
+
#++
|
|
5
|
+
|
|
6
|
+
module RubySGF
|
|
7
|
+
module SGF
|
|
8
|
+
#--
|
|
9
|
+
# this class is partially inspired by code written by
|
|
10
|
+
# Stefan Rusterholz, stefan.rusterholz <AT> gmail <DOT> com
|
|
11
|
+
#++
|
|
12
|
+
class Node
|
|
13
|
+
|
|
14
|
+
attr_reader :parent, :children, :number
|
|
15
|
+
attr_accessor :properties
|
|
16
|
+
|
|
17
|
+
def initialize(parent, properties = [])
|
|
18
|
+
@parent = parent
|
|
19
|
+
@properties = properties
|
|
20
|
+
@children = []
|
|
21
|
+
|
|
22
|
+
@parent << self if parent
|
|
23
|
+
|
|
24
|
+
if parent
|
|
25
|
+
@number = parent.number + 1
|
|
26
|
+
else
|
|
27
|
+
@number = 0
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def prev
|
|
32
|
+
@parent
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def next
|
|
36
|
+
@children[0]
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def [](index)
|
|
40
|
+
@children[index]
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def <<(node)
|
|
44
|
+
@children << node
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def leaf?
|
|
48
|
+
@children.empty?
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def root?
|
|
52
|
+
@parent.nil?
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def to_s
|
|
56
|
+
" "*@number << @number.to_s
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def write_tree(string="")
|
|
60
|
+
string << self.to_s << "\n"
|
|
61
|
+
@children.each do |child|
|
|
62
|
+
child.write_tree(string)
|
|
63
|
+
end
|
|
64
|
+
string
|
|
65
|
+
end # write_tree
|
|
66
|
+
end # class
|
|
67
|
+
end # sgf
|
|
68
|
+
end # rsgf
|
data/lib/sgf/property.rb
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
#--
|
|
2
|
+
# Copyright (c) 2008 Adam Prescott
|
|
3
|
+
# licensed as specified under LICENSE.txt
|
|
4
|
+
#++
|
|
5
|
+
|
|
6
|
+
module RubySGF
|
|
7
|
+
module SGF
|
|
8
|
+
class Property
|
|
9
|
+
|
|
10
|
+
DEFAULTS = {"AP" => "rGo:0.1a", "GM" => "1", "FF" => "4", "SZ" => "19", "PW" => "White", "PB" => "Black"}
|
|
11
|
+
|
|
12
|
+
attr_reader :name, :value
|
|
13
|
+
|
|
14
|
+
# /(PN\[((?:[^\]\\]+|\\[\]\[]?)*?)\])/ --> /(PN\[((?:[^\]\\]+|\\[\]\[]?)*?)\])+/
|
|
15
|
+
# allows lists to be taken into account [aa][ev][gg]
|
|
16
|
+
# returns PN[everything here including escaped \] like this]
|
|
17
|
+
MATCH = /(\[((?:[^\]\\]+|\\[\]\[]?)*?)\])/
|
|
18
|
+
MATCH_MANY = /(\[((?:[^\]\\]+|\\[\]\[]?)*?)\])+/
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def initialize(name, value)
|
|
22
|
+
@name = name
|
|
23
|
+
@value = value
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def human_name
|
|
27
|
+
Property.human_name_of(@name)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
class << self
|
|
31
|
+
|
|
32
|
+
def create_many_from_raw(text, properties)
|
|
33
|
+
properties.map! do |pn|
|
|
34
|
+
Property.create_from_raw(text,pn)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def create_from_raw(text, property_name)
|
|
39
|
+
prop_value = Property.parse_sgf(text, property_name) # Array, may be size 1 or more
|
|
40
|
+
prop_value.map! do |v|
|
|
41
|
+
if COORDINATE_PROPERTIES.include? property_name
|
|
42
|
+
Coordinates.new(v[0,1], v[1,1])
|
|
43
|
+
elsif property_name == "LB"
|
|
44
|
+
v = v.split(":")
|
|
45
|
+
v[0] = Coordinates.new(v[0][0,1], v[0][1,1])
|
|
46
|
+
v
|
|
47
|
+
else
|
|
48
|
+
v
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
new(property_name, prop_value)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# take a text of properties (NAME[VALUE], or otherwise) and return the value(s)
|
|
55
|
+
def parse_sgf(input, property_name)
|
|
56
|
+
$stderr << "invalid property detected (will be ignored): #{property_name} -- \"#{input}\"\n" unless Property.valid?(property_name)
|
|
57
|
+
match_many = MATCH_MANY.source
|
|
58
|
+
match = MATCH.source
|
|
59
|
+
output = ""
|
|
60
|
+
case property_name
|
|
61
|
+
when "C"
|
|
62
|
+
output = input[/#{property_name}#{match}/m][2..-2]
|
|
63
|
+
when "GN"
|
|
64
|
+
output = input[/#{property_name}#{match}/m][3..-2]
|
|
65
|
+
else
|
|
66
|
+
output = input.gsub("\n","")[/#{property_name}#{match_many}/][2..-1].scan(/[^\[\]]+/)
|
|
67
|
+
end
|
|
68
|
+
[*output]
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def valid?(name)
|
|
72
|
+
ALL_PROPERTY_NAMES.include?(name)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def compressed_list?(val)
|
|
76
|
+
val =~ /^[a-z][a-z]\:[a-z][a-z]$/i
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def expand_list(val)
|
|
80
|
+
ulx, uly, lrx, lry = val.scan(/^([a-z])([a-z])\:([a-z])([a-z])$/i).flatten
|
|
81
|
+
CompressedList.new(ulx, uly, lrx, lry).to_a
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def can_be_nil?(property_name)
|
|
85
|
+
["W","B"].include?(property_name)
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
private
|
|
90
|
+
|
|
91
|
+
class << self
|
|
92
|
+
def human_name_of(name)
|
|
93
|
+
PROPERTY_NAMES_HASH.invert[name]
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def sgf_name_of(sym)
|
|
97
|
+
PROPERTY_NAMES_HASH[sym]
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
data/lib/sgf/record.rb
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
#--
|
|
2
|
+
# Copyright (c) 2008 Adam Prescott
|
|
3
|
+
# licensed as specified under LICENSE.txt
|
|
4
|
+
#++
|
|
5
|
+
|
|
6
|
+
module RubySGF
|
|
7
|
+
module SGF
|
|
8
|
+
class Record
|
|
9
|
+
attr_reader :data, :root, :info
|
|
10
|
+
|
|
11
|
+
def initialize(data = nil)
|
|
12
|
+
@data = data
|
|
13
|
+
if data
|
|
14
|
+
@root = Record.create_tree(@data)
|
|
15
|
+
else
|
|
16
|
+
n = Node.new(nil)
|
|
17
|
+
n.properties = Property::DEFAULTS.map do |name, value|
|
|
18
|
+
Property.new(name, [value])
|
|
19
|
+
end
|
|
20
|
+
@root = n
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def to_s
|
|
25
|
+
@root.write_tree
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
private
|
|
29
|
+
|
|
30
|
+
class << self
|
|
31
|
+
def create_tree(str)
|
|
32
|
+
str = StringScanner.new(str)
|
|
33
|
+
root_node = node = nil
|
|
34
|
+
old_nodes = []
|
|
35
|
+
until str.eos?
|
|
36
|
+
case s = str.getch
|
|
37
|
+
when "("
|
|
38
|
+
old_nodes << node
|
|
39
|
+
node = Node.new(node)
|
|
40
|
+
root_node = node if node.root?
|
|
41
|
+
when ";"
|
|
42
|
+
# pass along all of the properties of the current node to Node for creation
|
|
43
|
+
# we ignore ; ( ) chars inside property values
|
|
44
|
+
node_text = str.scan(/[A-Z]+\[.*?\]\s*[;\(\)]/m).strip[0..-2]
|
|
45
|
+
# look for all property names
|
|
46
|
+
property_names = node_text.scan(/((?:[A-Z]+)(?:[^\\]|))\[/).flatten
|
|
47
|
+
$stderr << "Error around \"#{str.matched}\": multiple properties of the same type -- all but the first instance will be ignored\n" if property_names.uniq!
|
|
48
|
+
properties = Property.create_many_from_raw(node_text, property_names)
|
|
49
|
+
if node.properties.empty? # every node must have a property
|
|
50
|
+
node.properties = properties
|
|
51
|
+
else
|
|
52
|
+
node = Node.new(node, properties)
|
|
53
|
+
end
|
|
54
|
+
str.pos -= 1 # move back before the ; or ( or )
|
|
55
|
+
when ")"
|
|
56
|
+
node = old_nodes.pop
|
|
57
|
+
else
|
|
58
|
+
next
|
|
59
|
+
end # case
|
|
60
|
+
end # until
|
|
61
|
+
root_node
|
|
62
|
+
end # create_tree
|
|
63
|
+
end # singleton
|
|
64
|
+
end # record
|
|
65
|
+
end # SGF
|
|
66
|
+
end # RSGF
|
data/rubysgf.gemspec
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
Gem::Specification.new do |s|
|
|
2
|
+
s.name = "rubysgf"
|
|
3
|
+
s.version = "0.0.2"
|
|
4
|
+
s.date = "2008-08-22"
|
|
5
|
+
s.summary = "SGF file reader for Ruby"
|
|
6
|
+
s.email = "disaffect@gmail.com"
|
|
7
|
+
s.homepage = "http://github.com/theoros/rubysgf"
|
|
8
|
+
s.description = "A Ruby library to read SGF files and create objects out of them."
|
|
9
|
+
s.required_ruby_version = "~> 1.8.6"
|
|
10
|
+
s.has_rdoc = false
|
|
11
|
+
s.authors = ["Adam Prescott"]
|
|
12
|
+
s.files = ["LICENSE.txt",
|
|
13
|
+
"rubysgf.gemspec",
|
|
14
|
+
"lib/rubysgf.rb",
|
|
15
|
+
"lib/sgf/compressed_list.rb",
|
|
16
|
+
"lib/sgf/coordinates.rb",
|
|
17
|
+
"lib/sgf/errors.rb",
|
|
18
|
+
"lib/sgf/node.rb",
|
|
19
|
+
"lib/sgf/property.rb",
|
|
20
|
+
"lib/sgf/record.rb",
|
|
21
|
+
]
|
|
22
|
+
s.rdoc_options = []#["--main", "README.txt"]
|
|
23
|
+
s.extra_rdoc_files = []#["History.txt", "Manifest.txt", "README.txt"]
|
|
24
|
+
#s.add_dependency("mime-types", ["> 0.0.0"])
|
|
25
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: theoros-rubysgf
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.0.2
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Adam Prescott
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
|
|
12
|
+
date: 2008-08-22 00:00:00 -07:00
|
|
13
|
+
default_executable:
|
|
14
|
+
dependencies: []
|
|
15
|
+
|
|
16
|
+
description: A Ruby library to read SGF files and create objects out of them.
|
|
17
|
+
email: disaffect@gmail.com
|
|
18
|
+
executables: []
|
|
19
|
+
|
|
20
|
+
extensions: []
|
|
21
|
+
|
|
22
|
+
extra_rdoc_files: []
|
|
23
|
+
|
|
24
|
+
files:
|
|
25
|
+
- LICENSE.txt
|
|
26
|
+
- rubysgf.gemspec
|
|
27
|
+
- lib/rubysgf.rb
|
|
28
|
+
- lib/sgf/compressed_list.rb
|
|
29
|
+
- lib/sgf/coordinates.rb
|
|
30
|
+
- lib/sgf/errors.rb
|
|
31
|
+
- lib/sgf/node.rb
|
|
32
|
+
- lib/sgf/property.rb
|
|
33
|
+
- lib/sgf/record.rb
|
|
34
|
+
has_rdoc: false
|
|
35
|
+
homepage: http://github.com/theoros/rubysgf
|
|
36
|
+
post_install_message:
|
|
37
|
+
rdoc_options: []
|
|
38
|
+
|
|
39
|
+
require_paths:
|
|
40
|
+
- lib
|
|
41
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
42
|
+
requirements:
|
|
43
|
+
- - ~>
|
|
44
|
+
- !ruby/object:Gem::Version
|
|
45
|
+
version: 1.8.6
|
|
46
|
+
version:
|
|
47
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
48
|
+
requirements:
|
|
49
|
+
- - ">="
|
|
50
|
+
- !ruby/object:Gem::Version
|
|
51
|
+
version: "0"
|
|
52
|
+
version:
|
|
53
|
+
requirements: []
|
|
54
|
+
|
|
55
|
+
rubyforge_project:
|
|
56
|
+
rubygems_version: 1.2.0
|
|
57
|
+
signing_key:
|
|
58
|
+
specification_version: 2
|
|
59
|
+
summary: SGF file reader for Ruby
|
|
60
|
+
test_files: []
|
|
61
|
+
|