Awesome
@sabaki/sgf
A library for parsing SGF files.
Installation
Use npm to install:
$ npm install @sabaki/sgf
Usage
const sgf = require('@sabaki/sgf')
let rootNodes = sgf.parseFile('./game.sgf')
rootNodes
looks like this:
[
{
id: 1,
data: {B: ['dd'], ...},
parentId: null,
children: [
{
id: 2,
data: {W: ['dq']},
parentId: 1,
children: []
},
...
]
},
...
]
Use in the browser
You can use this library in the browser by using a bundler, such as webpack. If you do, you need to add the following lines to your webpack configuration:
{
...
externals: {
'fs': 'null',
// Add the next lines to disable automatic encoding detection
// and reduce bundle size:
'jschardet': 'null',
'iconv-lite': 'null'
}
}
Note that parseFile
is not available in the
browser; you have to use parse
instead.
Integration with @sabaki/immutable-gametree
This library uses the same node structure as @sabaki/immutable-gametree and is fully compatible with it. To wrap parsed SGF into game trees, you can write, for example, something like this:
const sgf = require('@sabaki/sgf')
const GameTree = require('@sabaki/immutable-gametree')
let getId = (id => () => id++)(0)
let rootNodes = sgf.parse(content, {getId})
let gameTrees = rootNodes.map(rootNode => {
return new GameTree({getId, root: rootNode})
})
Make sure the id generation function is shared between @sabaki/sgf
and
@sabaki/immutable-gametree
.
Contributors
A big thanks to @apetresc and @fohristiwhirl for adding decoding and automatic encoding detection functionalities.
API
Node Object
A tree node is represented by an object of the following form:
{
id: <Primitive>,
data: {
[property]: <Array<String>>
},
parentId: <Primitive> | null,
children: <Array<NodeObject>>
}
data
contains node properties which matches their
SGF property equivalent.
Basic Functions
*sgf.tokenizeIter(contents)
contents
<String>
- SGF input
A generator function that yields SGF tokens, objects of the following form:
{
type: <String>,
value: <String>,
row: <Integer>,
col: <Integer>,
pos: <Integer>,
progress: <Number>
}
type
is one of "parenthesis"
, "semicolon"
, "prop_ident"
,
"c_value_type"
, "invalid"
. row
is the zero-based index of the row where
the token starts, col
the zero-based index of column where the token starts,
and pos
denotes the index in contents
where the token starts. progress
is
a number between 0
and 1
denoting the percental position of the token.
sgf.tokenize(contents)
The same as sgf.tokenizeIter
, except this function
will return an array.
*sgf.tokenizeBufferIter(buffer[, options])
buffer
<Buffer>
- SGF inputoptions
<Object>
(optional)encoding
<String>
(optional)
A generator function that yields SGF tokens as in
sgf.tokenizeIter()
. If encoding
isn't set, we
will automatically choose an encoding. Automatic encoding detection is only
possible if optional dependencies are installed, otherwise UTF-8 will be used.
sgf.tokenizeBuffer(buffer[, options])
The same as sgf.tokenizeBufferIter
,
except this function will return an array.
sgf.parseTokens(tokens[, options])
tokens
- List of tokens as returned bysgf.tokenize()
options
<Object>
(optional)getId
<Function>
(optional)dictionary
<Object>
(optional)onProgress
<Function>
(optional)onNodeCreated
<Function>
(optional)
Returns an array of node objects which represent the root nodes of each game tree.
getId
can be specified to control the id generation. It will be called without
any arguments. By default, we will use consecutive integers starting at 0
as
ids.
Pass an object to dictionary
and it will get filled with references to all the
nodes with their ids as keys.
onProgress
will be called with an object with the following keys:
progress
<Number>
- Between0
and1
onNodeCreated
will be called when property parsing has been completed for a
node. It will be called with an object with the following keys:
node
<NodeObject>
sgf.parse(contents[, options])
contents
<String>
- SGF inputoptions
<Object>
(optional) - Seesgf.parseTokens()
Returns an array of node objects.
sgf.parseBuffer(buffer[, options])
buffer
<Buffer>
- The bufferoptions
<Object>
(optional)encoding
<String>
(optional) - Seesgf.tokenizeBuffer()
getId
<Function>
(optional) - Seesgf.parseTokens()
dictionary
<Object>
(optional) - Seesgf.parseTokens()
onProgress
<Function>
(optional) - Seesgf.parseTokens()
Returns an array of node objects.
sgf.parseFile(filename[, options])
filename
<String>
- Path to an SGF fileoptions
<Object>
(optional) - Seesgf.parseBuffer()
Returns an array of node objects. Automatically detects encoding.
sgf.stringify(nodes[, options])
nodes
<NodeObject[]>
options
<Object>
(optional)linebreak
<String>
(optional) - Default:"\n"
indent
<String>
(optional) - Default:" "
Returns an SGF string representing the root nodes nodes
.
Helper Functions
sgf.escapeString(input)
input
<String>
Escapes \
and ]
characters and returns the new string.
sgf.unescapeString(input)
input
<String>
Resolves escaped characters and returns the new string.
sgf.parseVertex(input)
input
<String>
Turns an SGF point string into a vertex, an integer array of the form [x, y]
.
An invalid string will yield [-1, -1]
.
sgf.stringifyVertex(vertex)
vertex
<Integer[]>
Turns a vertex into an SGF point string. Returns an empty string if vertex is invalid.
sgf.parseCompressedVertices(input)
input
<String>
Turns an SGF compressed point list into an array of vertices.
sgf.parseDates(input)
input
<String>
Parses an SGF date string into an array of date arrays, integer arrays of the
form [year, month, date]
.
sgf.stringifyDates(dates)
dates
<Integer[][]>
Turns an array of date arrays and returns an SGF date string.