Package-Name: glGo-SGFTools
Requires: python
Homepage: http://www.pandanet.co.jp/English/glgo/sgftools/
Source: http://www.pandanet.co.jp/English/glgo/sgftools//(glGo-SGFTools-(\d+(\.\d+)+)\.tar\.gz)/[\0-\377]*?glGo-SGFTools-(\d+(.\d+)+).tar.gz $1
Zap-Before-Install: 1
Repack:
	tar xzvfp "$(SOURCE)"
Compile:
	cp -pf README "$(PREFIX)/"
	python setup.py build
	rm -rf "$(PREFIX)"/bin
	mkdir -p "$(PREFIX)"/bin
	cp -p build/scripts*/{ugf,ishi}2sgf.py "$(PREFIX)"/bin/
	rm -rf "$(PREFIX)"/lib
	mkdir -p "$(PREFIX)"/lib/python/site-packages
	cp -a build/lib/glGo "$(PREFIX)"/lib/python/site-packages/
Install:
	$(MAKE) instbin BIN="ugf2sgf.py ishi2sgf.py"
	rm -rf /usr/lib/python*/site-packages/glGo
	ln -s "$(PREFIX)"/lib/python/site-packages/glGo /usr/lib/python/site-packages
Patch: <<EOT
######## begin use new pass notation patch
--- glGo/ugf/ugf2sgf_converter.py.old	2005-11-29 21:40:17 +0900
+++ glGo/ugf/ugf2sgf_converter.py	2005-12-01 00:53:58 +0900
@@ -35,8 +35,8 @@
             # Write something like 'B[aa]'
             str += "%s[%s%s]" % (c, chr(96 + self.x), chr(96 + self.y))
         elif (self.x == -1 and self.y == -1) or (self.x == 20 and self.y == 20):
-            # Pass: 'B[tt]'
-            str += "%s[tt]", c
+            # Pass: 'B[]'
+            str += "%s[]", c
 
         # Save marks, if we have any
         if self.marks:
######## end use new pass notation patch
######## begin UGF importation fixup patch
--- glGo/ugf/ugf2sgf_converter.py.old	2005-12-01 00:55:08 +0900
+++ glGo/ugf/ugf2sgf_converter.py	2005-12-01 01:02:32 +0900
@@ -13,18 +13,22 @@
 from string import replace, rstrip
 
 class Move:
-    def __init__(self, x, y, col):
+    def __init__(self, x, y, col, num):
         self.x = x
         self.y = y
         self.color = col
+        if num == 0:
+            self.initial = True
+        else:
+            self.initial = False
         self.comment = None
         self.marks = []
 
-    def MoveToSGF(self, is_root=False):
-        if not is_root:
-            str = ";"
+    def MoveToSGF(self):
+        if self.initial:
+            str = "A"  # so we get "AB" and "AW"
         else:
-            str = ""  # No ";" for root node
+            str = ";"
 
         if self.color == STONE_BLACK:
             c = "B"
@@ -34,6 +38,9 @@
         if self.x > 0 and self.y > 0:
             # Write something like 'B[aa]'
             str += "%s[%s%s]" % (c, chr(96 + self.x), chr(96 + self.y))
+            if not self.initial:
+                # Add a circle to the current move
+                str += "CR[%s%s]" % (chr(96 + self.x), chr(96 + self.y))
         elif (self.x == -1 and self.y == -1) or (self.x == 20 and self.y == 20):
             # Pass: 'B[]'
             str += "%s[]", c
@@ -70,11 +77,14 @@
 game = []
 
 def do_move(move):
-    game.append(Move(move[0][0], move[0][1], move[1]))
+    game.append(Move(move[0][0], move[0][1], move[1], move[2]))
 
 def do_comment(comment):
     if game:
-        game[len(game)-1].comment = comment
+        if game[len(game)-1].comment:
+            game[len(game)-1].comment += "\n\n" + comment
+        else:
+            game[len(game)-1].comment = comment
 
 def do_mark(pos, text):
     if game:
@@ -100,11 +110,8 @@
 
     # Write moves.
     # Unlike the C++ SGF writer, we don't need to traverse as we don't have a tree
-    is_root = True
     for m in game:
-        file.write(m.MoveToSGF(is_root) + "\n")
-        if is_root:
-            is_root = False
+        file.write(m.MoveToSGF() + "\n")
     file.write(")\n")
 
     file.close()
@@ -120,6 +127,7 @@
 
     # Charset TODO
     # s += "CA[" + data.charset + "]" +
+    s += "CA[UTF-8]"
 
     # Application name : Version
     s += "AP[%s:%s]" % (__init__.packagename , sgftools_version)
--- glGo/ugf/ugf_parser.py.old	2005-03-11 12:13:39 +0900
+++ glGo/ugf/ugf_parser.py	2005-11-30 16:03:10 +0900
@@ -13,7 +13,7 @@
 STONE_BLACK     = 2
 
 boardsize = 19
-jpn_coords_flag = False
+jpn_coords_flag = True
 comments = []
 marks = []
 
@@ -49,7 +49,7 @@
     toParse = getSection(ugf, "\[Header\]", ("\[Data\]", "\[Remote\]"))
     if not toParse:
         return -1
-    rex = re.compile(r"(([a-zA-Z]+)=(.*\n))")
+    rex = re.compile(r"(([a-zA-Z0-9]+)=(.*\n))")
     headers = rex.findall(toParse)
     for h in headers:
         parseHeader(h[1], h[2].strip())
@@ -58,7 +58,7 @@
     # We parse this before the Data section to collect comments and marks.
     toParse = getSection(ugf, "\[Figure\]", ("",), testEOF=True)
     if toParse:  # I guess it's no error if figure is missing. No idea.
-        rex = re.compile(r"(.Text,[0-9]+\n)(((?![.]E).*\n)*)(.EndText)")
+        rex = re.compile(r"(.Text,[0-9]+(?:,[0-9]+)+\n)(((?![.]E).*\n)*)(.EndText)")
         texts = rex.findall(toParse)
         for t in texts:
             parseFigure(t[0], t[1])
@@ -87,6 +87,11 @@
 def parseHeader(key, value):
     # print "Header: %s  -  %s" % (key, value)
 
+    if key == "BMemb1":
+        key = "PlayerB"
+    if key == "WMemb1":
+        key = "PlayerW"
+
     if key == "Size":
         global boardsize
         boardsize = int(value)
@@ -103,6 +108,8 @@
         pos = value.find(",")
         if pos != -1:
             value = value[0:pos]
+        # Convert YYYY/MM/DD to YYYY-MM-DD
+        value = string.replace(value, "/", "-")
     elif key == "Hdcp":
         pos = value.find(",")
         if pos != -1:
@@ -114,18 +121,65 @@
                 value = handi
             except:
                 return
-    elif key == "PlayerW" or key == "PlayerB":
+    elif key == "PlayerW" or key == "PlayerB" or key == "Commentator":
         pos1 = value.find(",")
         if pos1 != -1:
             name = value[0:pos1]
             pos2 = value.find(",", pos1+1)
             if pos2 != -1:
                 rank = value[pos1+1:pos2]
-                if key == "PlayerW":
-                    which = "WhiteRank"
-                else:
-                    which = "BlackRank"
-                doHeader(which, rank)  # Cheat again
+                if key == "Commentator":
+                    name += rank
+                elif rank:
+                    if key == "PlayerW":
+                        which = "WhiteRank"
+                    else:
+                        which = "BlackRank"
+                    if rank == u"\u521D\u6BB5".encode("utf8"):
+                        rank = "1p"
+                    if rank == u"\u4E8C\u6BB5".encode("utf8"):
+                        rank = "2p"
+                    if rank == u"\u4E09\u6BB5".encode("utf8"):
+                        rank = "3p"
+                    if rank == u"\u56DB\u6BB5".encode("utf8"):
+                        rank = "4p"
+                    if rank == u"\u4E94\u6BB5".encode("utf8"):
+                        rank = "5p"
+                    if rank == u"\u516D\u6BB5".encode("utf8"):
+                        rank = "6p"
+                    if rank == u"\u4E03\u6BB5".encode("utf8"):
+                        rank = "7p"
+                    if rank == u"\u516B\u6BB5".encode("utf8"):
+                        rank = "8p"
+                    if rank == u"\u4E5D\u6BB5".encode("utf8"):
+                        rank = "9p"
+                    if rank == u"\u68CB\u8056".encode("utf8"):  # kisei
+                        rank = "9p"
+                    if rank == u"\u540D\u4EBA".encode("utf8"):  # meijin
+                        rank = "9p"
+                    if rank == u"\u672C\u56E0\u574A".encode("utf8"):  # honinbou
+                        rank = "9p"
+                    if rank == u"\u5341\u6BB5".encode("utf8"):  # jyudan
+                        rank = "9p"
+                    if rank == u"\u5929\u5143".encode("utf8"):  # tengen
+                        rank = "9p"
+                    if rank == u"\u738B\u5EA7".encode("utf8"):  # ouza
+                        rank = "9p"
+                    if rank == u"\u7881\u8056".encode("utf8"):  # gosei
+                        rank = "9p"
+                    rank = string.replace(rank, u"\uFF10".encode("utf8"), "0");
+                    rank = string.replace(rank, u"\uFF11".encode("utf8"), "1");
+                    rank = string.replace(rank, u"\uFF12".encode("utf8"), "2");
+                    rank = string.replace(rank, u"\uFF13".encode("utf8"), "3");
+                    rank = string.replace(rank, u"\uFF14".encode("utf8"), "4");
+                    rank = string.replace(rank, u"\uFF15".encode("utf8"), "5");
+                    rank = string.replace(rank, u"\uFF16".encode("utf8"), "6");
+                    rank = string.replace(rank, u"\uFF17".encode("utf8"), "7");
+                    rank = string.replace(rank, u"\uFF18".encode("utf8"), "8");
+                    rank = string.replace(rank, u"\uFF19".encode("utf8"), "9");
+                    rank = string.replace(rank, u"\u6BB5".encode("utf8"), "d");
+                    rank = string.replace(rank, u"\u7D1A".encode("utf8"), "k");
+                    doHeader(which, rank)  # Cheat again
             value = name
     elif key == "Winner":
         result = ""
@@ -147,7 +201,7 @@
         #    print "Result: " + result
         value = result
     elif key == "Title":
-        value = value.strip(",")
+        value = string.replace(value, ",", "")
 
     # Security check against buffer overflow. These embedded images
     # in PandaNet magazine files are shocking. :)
@@ -194,6 +248,9 @@
             print "Failed to parse figure: %s" % figure
         return
     move_num = int(so.group(1))
+    # Move 0 (comment before first move) isn't valid for SGF?
+    if move_num == 0:
+        move_num = 1
 
     # Parse comment
     rex = re.compile(r"((?![.][#]).*\n)*")
@@ -303,6 +360,8 @@
 
     # Get rid of Windows carriage crap
     s = string.replace(s, "\r\n", "\n")
+    # Convert to UTF8
+    s = unicode(s, "sjis", "replace").encode("utf8")
     return parse(s)
 
 
######## end UGF importation fixup patch
EOT

/pkg/glGo-SGFTools/
/usr/bin/ishi2sgf.py
/usr/bin/ugf2sgf.py
/usr/lib/python*/site-packages/glGo
