Skip to content
/ sgf Public

A library for parsing SGF files.

License

Notifications You must be signed in to change notification settings

SabakiHQ/sgf

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

@sabaki/sgf Build Status

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.

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 input
  • options <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 by sgf.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> - Between 0 and 1

onNodeCreated will be called when property parsing has been completed for a node. It will be called with an object with the following keys:

sgf.parse(contents[, options])

Returns an array of node objects.

sgf.parseBuffer(buffer[, options])

Returns an array of node objects.

sgf.parseFile(filename[, options])

  • filename <String> - Path to an SGF file
  • options <Object> (optional) - See sgf.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.