NAME

Games::Go::SGF2misc - Reads SGF files and produces usable output in many formats

SYNOPSIS

use Games::Go::SGF2misc;

my $sgf = new Games::Go::SGF2misc;
for my $file (<*.sgf>) {
    $sgf->parse($file);

    # do things with the parsed sgf:
    # the output options are listed below
}

nodelist

my $nodelist = $sgf->nodelist;  

# This returns a special list of node-id's (human readable
# $game_number.$variation-$move_no node descriptors).  example:

$nodelist = { 1 => [
    [ '1.1-root', '1.1-1', '1.1-2', '1.1-3', '1.1-4', '1.1-5', ],
    [      undef,   undef,   undef,   undef,   undef, '1.2-5', '1.2-6', '1.2-7', ],
    [      undef,   undef,   undef,   undef,   undef,   undef,   undef, '1.3-7', '1.3-8' ],
] };

# What do you do with them?

as_perl

my $game_info = $sgf->as_perl(1);
my $root_node = $sgf->as_perl('1.1-root');
my $move5_v2  = $sgf->as_perl('1.2-5');

my $s = $game_info->{game_properties}{SZ};
print "The board size is: ${s}x${s}!\n"; 

print my $c (@{ $move5_v2->{comments} }) {
    print "Comment from 1.2-5: $c\n";
}

# Tada!!

# Oh, as_perl takes an optional second argument.

$sgf->as_perl("doesn't exist node"); # will die on the spot...
$sgf->as_perl("isn't there", 1)      # will not
    or print "yikes!!: " . $sgf->errstr;

as_text

# This is pretty much just an example

use strict;
use Games::Go::SGF2misc;

my $sgf = new Games::Go::SGF2misc; 
   $sgf->parse("sgf/jettero-sixrusses-2004-03-18.sgf");

my $nl  = $sgf->nodelist;
my $end = $nl->{1}[0][ $#{$nl->{1}[0]} ];
          # 1st game  1st variation    last node
 
my $caps = $sgf->as_perl( $end )->{captures};

print $sgf->as_text($end), "Captures:  Black-$caps->{B} / White-$caps->{W}\n";

# Result:
#   X O . . . O . . . . . . . . . O O O .
#   . O O . O O X . X X O O X O O O X X X
#   X O . . . O X . X O . O O . O X . . .
#   O O . O O X O O O O O . . O X . X . .
#   O O O O O X X X X O . O O X . . . . .
#   O X X X O X . X . X O O X . X . . . .
#   X X X O O . X . X . X X . . . . . . .
#   X . . X O . . X . . . . . . . . X . .
#   X . X X O O O X . . . . . . . . . . .
#   X . X . X X O X O O O X . . . . . . .
#   . X . . . X O O X X X X X . . . X . .
#   . . . . X O O . O O O X . . . X X X X
#   X X X . X X O O . O X X X . . X O O X
#   X O O X . . X . O O O X X . X O O . O
#   O O . O X X X X X O X X O X X X O . .
#   . . O O O X . . X O O X O X O X O X .
#   . . . . O O X X O O . O O O O O O X .
#   . . . . . O X O . O . . . . O X X O O
#   . . . . . O X O O . . . . . . . . . .
#   Captures:  Black-11 / White-16

as_html

# This function works very much like the as_text function above, but
# instead prints out an html table full of images.

open OUT, ">example.html" or die $!;
print OUT, $sgf->as_html( $end, "/image/dir/" );

# The only real difference is the image-dir argument (which defaults to
# "./img").  This is the URL image dir (<img # src="$image_dir/moku.gif">), 
# not the pysical image dir.  There is a directory of images included
# with SGF2misc.  They are from this page:

# http://www.britgo.org/gopcres/gopcres1.html#ag-gifs

# They are Andrew Grant's GIF images.  I did NOT seek permission to
# re-distribute them.  Perhaps I have no right to do so.  I really
# don't know how to get ahold of him.  

# If anyone knows how who to ask, please tell me.  If anyone knows it's
# a problem, please tell me.

# 3/22/04, Orien Vandenbergh made bc.gif, wc.gif, bq.gif and wq.gif for me.

# NOTE: On marks, this as_html only shows circles, triangles, squares,
# and numbers where there are stones.  It does not show letters at all.
# This is only because I don't have images for _everything_. :)

as_image

# This uses the fantastic ::SGF2misc::GD package by Orien Vandenbergh
# that comes with this package.  It is a separate package, and as you
# will see, the interfaces aren't totally compatable -- however, it
# _is_ intended to be used with this package.

# You must install GD-2.15 (or so) in order to use it!!  You will also
# need the bleeding edge versions of libpng and libgd.  At the time of
# this writing, I used libgd-2.0.22 and got GD-2.12 to install and
# function normally.

# Here's a calling example:
$sgf->as_image($node, {filename=>"html/$x->[$i].png", gobanColor=>[255, 255, 255]});

# ::SGF2misc::GD takes hash-like arguments.  So, so does as_image().
# filename=>"" and gobanColor=>[] are additions of mine, as they're
# actually used on separate calls in the ::SGF2misc::GD package.
# All other arguments are passed to the new() member function if
# ::SGF2misc::GD.  Please read the Games::Go::SGF2misc::GD manpage; it
# contains much more information.

# Some SGF writers will automatically add a CR (circle) property to
# the current move, which as_image will render as expected.  However
# other SGF writers do not.  To have as_image automatically render
# circles on the current moves add the hash argument auto_mark=>1.
# With auto_mark enabled, any nodes which already have _any_ form of
# markup will not receive _any_ circles on the current moves.  This
# is to help ensure consistancy with SGFs where the markup has other
# (more important?) uses.*This could have undesirable results for
# nodes in which there are multiple stones placed.

# Also, in the interests of making this as clumsy as possible, if the
# filename is a dash followed by a type extension,

    my $image = $sgf->as_image($l, {filename=>"-.png"});

# then the image will be returned as a string rather than written to a
# file.  

# Optionally, you can also install the ::SGF2misc::SVG package written
# by Orien.  To specify use of the SVG module call as_image with the 
# argument 'use' => 'Games::Go::SGF2misc::SVG'.  Functionally the two 
# rendering modules are equivalent, except SVG doesn't yet support
# returning the image as a string.  Aesthetically, however, ::SVG
# seems to render a cleaner image (at all resolutions), and does so
# significantly faster.

as_freezerbag

# What?  Yeah, this is a special way to save the parsed sgf data such
# that you can interact with it without having to re-parse it.  It
# seemed like it should be faster than re-parsing the SGF every time,
# but it isn't much of a speedup at all.  Unless I can speed it up, or
# someone asks me to leave it in, it could get axed.  I may leave it in
# anyway, because it's cute.

# Try it yourself:

 $sgf->as_freezerbag( "freezer.pl",  # an export filename

     # Some code to put in it.  This argument is optional.
         q/my @nodes = @{ $sgf->nodelist->{1}[0] };

         for my $n (@nodes) {
             my $board = $sgf->as_text($n) or die $sgf->errstr; 
             print "\e[1;1f$board";
         }/,

    # The location and/or switches for your perl
    # I needed blib/lib (since I don't always install to test this
    # stuff).  This argument is optional.

    "/usr/bin/perl -I blib/lib",
 );

Board Postion Character Map

# This is how an empty 3x3 board would be stored:

$board = [
    [ ' ', ' ', ' ' ],
    [ ' ', ' ', ' ' ],
    [ ' ', ' ', ' ' ],
];

# ' ' - an empty board position
# 'W' - a white stone
# 'B' - a black stone

# Marks are not placed on the board!
# You'll just have to fetch the marks array from the $node.

Miscellaneous

is_node

print "There is a node called 1.1-root!\n" if $sgf->is_node('1.1-root');

BUGS

Besides the lack of documentation?  Well, I'm sure there's a bunch.
If you spot any bugs, please tell me.

ENV VARIABLES

DEBUG

Try setting $ENV{DEBUG}=1, $ENV{DEBUG}=2, or $ENV{DEBUG}=3 to see the internals.

Also, from your bash prompt you can 'DEBUG=1 perl ./myprog.pl' to
enable debugging dynamically.

DEBUG of 31 or over will show the lexical trace.  That's kinda fun.

AUTHOR

Please contact me with ANY suggestions, no matter how pedantic.

Jettero Heller <jettero@cpan.org>

Some changes and patches provided by:

Orien Vandenbergh <orien@icecode.com>

COPYRIGHT

GPL!  I included a gpl.txt for your reading enjoyment.

Though, additionally, I will say that I'll be tickled if you were to
include this package in any commercial endeavor.  Also, any thoughts to
the effect that using this module will somehow make your commercial
package GPL should be washed away.

I hereby release you from any such silly conditions.

This package and any modifications you make to it must remain GPL.  Any
programs you (or your company) write shall remain yours (and under
whatever copyright you choose) even if you use this package's intended
and/or exported interfaces in them.