Files @ 69f9170d3c89
Branch filter:

Location: Diana/src/sgfParser/node.py - annotation

Laman
cleaned redundant whitespace in SVG, cleaned old files
ef10e626e192
ef10e626e192
0ee71f3564f4
cfcff53c74e6
b66f5379b832
b66f5379b832
b66f5379b832
b66f5379b832
b66f5379b832
2ed7f0dab5ef
2ed7f0dab5ef
b66f5379b832
b66f5379b832
0ee71f3564f4
0ee71f3564f4
0ee71f3564f4
0ee71f3564f4
b66f5379b832
0ee71f3564f4
b66f5379b832
0ee71f3564f4
b66f5379b832
0ee71f3564f4
0ee71f3564f4
b66f5379b832
0ee71f3564f4
0ee71f3564f4
b66f5379b832
b66f5379b832
b66f5379b832
b66f5379b832
b66f5379b832
ef10e626e192
ef10e626e192
ef10e626e192
ef10e626e192
ef10e626e192
ef10e626e192
ef10e626e192
ef10e626e192
ef10e626e192
ef10e626e192
ef10e626e192
ef10e626e192
ef10e626e192
ef10e626e192
ef10e626e192
ef10e626e192
ef10e626e192
ef10e626e192
ef10e626e192
ef10e626e192
b66f5379b832
cfcff53c74e6
b66f5379b832
ef10e626e192
b66f5379b832
b66f5379b832
b66f5379b832
2ed7f0dab5ef
2ed7f0dab5ef
ef10e626e192
b66f5379b832
b66f5379b832
2ed7f0dab5ef
ef10e626e192
2ed7f0dab5ef
b66f5379b832
b66f5379b832
b66f5379b832
2ed7f0dab5ef
b66f5379b832
2ed7f0dab5ef
ef10e626e192
b66f5379b832
b66f5379b832
b66f5379b832
2ed7f0dab5ef
2ed7f0dab5ef
2ed7f0dab5ef
ef10e626e192
b66f5379b832
b66f5379b832
b66f5379b832
ef10e626e192
2ed7f0dab5ef
2ed7f0dab5ef
2ed7f0dab5ef
2ed7f0dab5ef
2ed7f0dab5ef
2ed7f0dab5ef
ef10e626e192
b9d29dcfe3d8
ef10e626e192
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 collections import deque

from . import skipWhitespace, ParserWarning
from .property import Property, GAME_INFO


class Node:
	def __init__(self):
		self.properties=dict()
		self.parent=None
		self.children=[]

	@staticmethod
	def fits(s,i):
		return i<len(s) and s[i]==";"

	@staticmethod
	def create(s,start):
		assert Node.fits(s,start)
		res=Node()

		i=skipWhitespace(s,start+1)
		while Property.fits(s,i):
			i,x=Property.create(s,i)
			if x.name in res.properties:
				# !! raise or log or ignore
				raise ParserWarning('duplicate "{0}" property in a node. second value ignored'.format(x.name),s,i)
			else:
				res.properties[x.name]=x
			i=skipWhitespace(s,i)
		return (i,res)

	def listGINodes(self):
		if self.isGINode(): yield self
		empty=not self.isGINode()

		node=self
		while node.parent:
			node=node.parent
			if node.isGINode():
				empty=False
				yield node

		queue=deque(self.children)
		while len(queue)>0:
			node=queue.popleft()
			if node.isGINode():
				empty=False
				yield node
			queue.extend(node.children)
		if empty: yield self # always yield at least self, can work as GINode as well as any other

	def isGINode(self):
		return any(prop.type==GAME_INFO for prop in self.properties.values())

	def setProp(self,name,value):
		self.properties[name]=value
		# zkontrolovat typ value

	def setChildren(self,children):
		self.children=children
		for child in children: child.parent=self

	def addChild(self,node):
		if node in self.children: return node
		node.parent=self
		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)]
		node.parent=None
		return node

	def removeChildAt(self,i):
		if -len(self.children)<i<len(self.children):
			res=self.children[i]
			del self.children[i]
			res.parent=None
			return res
		return None

	## Create a copy of the Node, with the same parent and deep copied properties, no copied children.
	def copy(self):
		res=Node()
		res.properties={k: v.copy() for (k,v) in self.properties.items()}
		res.parent=self.parent
		return res

	def getProp(self,name,default=None):
		if name in self.properties: return self.properties[name].value
		else: return default

	## 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)