Files @ b9d29dcfe3d8
Branch filter:

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

Laman
svg rendering
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 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 getProp(self,name):
		if name in self.properties: return self.properties[name].value
		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)