Files
@ a362783e3bec
Branch filter:
Location: Diana/src/sgfParser/node.py - annotation
a362783e3bec
2.5 KiB
text/x-python
exporting SGF back to string, also useful Composed and Point property classes
b66f5379b832 cfcff53c74e6 b66f5379b832 b66f5379b832 b66f5379b832 b66f5379b832 b66f5379b832 2ed7f0dab5ef 2ed7f0dab5ef b66f5379b832 b66f5379b832 b66f5379b832 b66f5379b832 b66f5379b832 b66f5379b832 b66f5379b832 b66f5379b832 b66f5379b832 b66f5379b832 b66f5379b832 b66f5379b832 b66f5379b832 b66f5379b832 b66f5379b832 b66f5379b832 b66f5379b832 b66f5379b832 b66f5379b832 b66f5379b832 cfcff53c74e6 b66f5379b832 b66f5379b832 b66f5379b832 b66f5379b832 b66f5379b832 b66f5379b832 2ed7f0dab5ef 2ed7f0dab5ef 2ed7f0dab5ef 2ed7f0dab5ef b66f5379b832 b66f5379b832 2ed7f0dab5ef 2ed7f0dab5ef b66f5379b832 b66f5379b832 b66f5379b832 2ed7f0dab5ef b66f5379b832 2ed7f0dab5ef b66f5379b832 b66f5379b832 b66f5379b832 2ed7f0dab5ef 2ed7f0dab5ef 2ed7f0dab5ef b66f5379b832 b66f5379b832 b66f5379b832 2ed7f0dab5ef 2ed7f0dab5ef 2ed7f0dab5ef 2ed7f0dab5ef 2ed7f0dab5ef 2ed7f0dab5ef 2ed7f0dab5ef 2ed7f0dab5ef b66f5379b832 b66f5379b832 b66f5379b832 a362783e3bec a362783e3bec a362783e3bec a362783e3bec a362783e3bec a362783e3bec a362783e3bec a362783e3bec a362783e3bec a362783e3bec a362783e3bec a362783e3bec a362783e3bec a362783e3bec a362783e3bec a362783e3bec a362783e3bec a362783e3bec a362783e3bec a362783e3bec a362783e3bec a362783e3bec a362783e3bec a362783e3bec a362783e3bec a362783e3bec | from . import skipWhitespace, ParserError
from .property import Property, GAME_INFO
class Node:
def __init__(self):
self.properties=dict()
self.parent=None
self.children=[]
@staticmethod
def create(s,start):
res=Node()
if s[start]!=";":
# print("error when parsing Node")
return (start,None)
i=skipWhitespace(s,start+1)
i,x=Property.create(s,start+1)
while x is not None:
if x.name in res.properties:
print(res.properties)
raise ParserError(0,0,'duplicate "{0}" property in node at position {1}. second value ignored'.format(x.name,start))
else:
res.properties[x.name]=x
i=skipWhitespace(s,i)
i,x=Property.create(s,i)
return (i,res)
def isGINode(self):
return any(prop.type==GAME_INFO for prop in self.properties.values())
def setProperty(self,name,value):
self.properties[name]=value
# zkontrolovat typ value
def setParent(self,node):
self.parent=node
def setChildren(self,children):
self.children=children
def addChild(self,node):
if node in self.children: return node
self.children.append(node)
return node
def removeChild(self,node):
if node not in self.children:
return None
del self.children[self.children.index(node)]
return node
def removeChildAt(self,i):
if -len(self.children)<i<len(self.children):
res=self.children[i]
del self.children[i]
return res
return None
## Create a copy of the Node, with deep copied propeties and shallow copied parent and children.
def copy(self):
res=Node()
res.properties={k: v.copy() for (k,v) in self.properties.items()}
res.parent=self.parent
res.setChildren(self.children[:])
return res
def getProperty(self,name):
if name in self.properties: return self.properties[name]
else: return None
## Returns textual representation of the Node itself, but disregards its children.
def __str__(self):
return ";" + "".join(str(p) for p in self.properties.values())
def export(self):
# there is a beatiful recursive solution, which this stack is too narrow to contain
stack=[(self,1,1)]
output=[]
while len(stack)>0:
node,left,right=stack.pop()
if left>0: output.append("("*left)
output.append(str(node))
childCount=len(node.children)
if childCount==0: # a leaf
output.append(")"*right)
elif childCount==1: # a line
stack.append((node.children[0],0,right))
else: # a branching node
# first child pops first, last child closes parent's parentheses
children=zip(node.children,[1]*childCount,[1]*(childCount-1)+[1+right])
stack.extend(reversed(children))
return "".join(output)
|