diff --git a/diana.py b/diana.py
new file mode 100644
--- /dev/null
+++ b/diana.py
@@ -0,0 +1,199 @@
+import sys
+import re
+import go
+import os
+import sgf
+
+if len(sys.argv)>1:
+ files=sys.argv[1:]
+else:
+ sys.exit("no input file specified")
+
+movesPerDiagram=50
+minMovesPerDiagram=10
+
+t=sys.stdout
+c=28
+padding=15
+highNumbers=False
+
+class Svg:
+ content=""
+ footer=""
+
+ padding=15
+ gridSize=28
+ highNumbers=False
+
+ def __init__(self):
+ self.content='''
+\n"
+
+ grid=' \n'
+
+ # okraje desky
+ for i in (0,18):
+ self.content+=' \n'.format(self.padding, 18*self.gridSize+self.padding, self.gridSize*i+self.padding, self.gridSize*i+self.padding)
+ self.content+=' \n'.format(self.gridSize*i+self.padding, self.gridSize*i+self.padding, self.padding, 18*self.gridSize+self.padding)
+
+ # mřížka
+ for i in range(1,18):
+ self.content+=grid.format(padding, 18*c+padding, c*i+padding, c*i+padding)
+ self.content+=grid.format(c*i+padding, c*i+padding, padding, 18*c+padding)
+
+ # hvězdy
+ for i in range(3):
+ for j in range(3):
+ self.content+=' \n'.format(padding+3*c+6*i*c, padding+3*c+6*j*c, 2)
+
+ def __str__(self):
+ return self.content+self.footer
+
+ def drawStone(self,x,y,color):
+ self.content+=' \n'.format(padding+x*c, padding+y*c, c/2-1, color)
+
+ def getFontSize(self,text):
+ if len(text)<2: return round(0.7*c)
+ elif len(text)<3: return round(0.55*c)
+ else: return round(0.4*c)
+
+ def writeLabel(self,x,y,label,color):
+ label=str(label)
+ fontSize=self.getFontSize(label)
+ self.content+=' {4}\n'.format(padding+x*c, padding+y*c+0.35*fontSize, color, fontSize, label)
+
+ def drawMove(self,x,y,label,color):
+ labelColor="w" if color=="b" else "b"
+
+ if (not self.highNumbers) and isinstance(label,int) and label%100!=0: label=label%100 # dost neobratná logika
+
+ self.drawStone(x,y,color)
+ self.writeLabel(x,y,label,labelColor)
+
+ def getContent(self):
+ return self.content+self.footer
+
+
+class Tikz:
+ content=""
+ footer=""
+
+ highNumbers=False
+
+ def __init__(self):
+ self.content='''\\begin{tikzpicture}
+ \\draw[step=\\boardSquare,gray,very thin] (0,0) grid (18\\boardSquare,18\\boardSquare);
+ \\draw (0,0) rectangle (18\\boardSquare,18\\boardSquare);\n\n'''
+
+ # hvězdy
+ for i in range(3):
+ for j in range(3):
+ self.content+=' \\filldraw[fill=black] ({0}\\boardSquare,{1}\\boardSquare) circle[radius=0.04];\n'.format(6*i+3, 6*j+3)
+ self.content+='\n'
+
+ self.footer='\\end{tikzpicture}\n'
+
+ def __str__(self):
+ return self.content+self.footer
+
+ def drawStone(self,x,y,color):
+ fill="black" if color=="b" else "white"
+ self.content+=' \\filldraw[draw=black,fill={0}] ({1}\\boardSquare,{2}\\boardSquare) circle[radius=0.5\\boardSquare];\n'.format(fill,x,18-y)
+
+ def drawMove(self,x,y,label,color):
+ fill="black" if color=="b" else "white"
+ labelColor="white" if color=="b" else "black"
+ if (not self.highNumbers) and isinstance(label,int) and label%100!=0: label=label%100 # dost neobratná logika
+
+ self.content+=' \\filldraw[draw=black,fill={0}] ({1}\\boardSquare,{2}\\boardSquare) circle[radius=0.5\\boardSquare] node[color={3}]{{{4}}};\n'.format(fill,x,18-y,labelColor,label)
+
+ def getContent(self):
+ return self.content+self.footer
+
+
+def processFile(fileName):
+ shortName="".join(fileName.split('/')[-1].split('.')[:-1])
+
+ game=go.Go()
+ global t
+
+ record=sgf.Sgf(open(fileName,'r',encoding="utf-8").read())
+ moves=record.getMoves()
+
+ localBoard=dict()
+ overlays=""
+ letters=dict()
+ letter='a'
+
+ diagramsNeeded=(len(moves)-minMovesPerDiagram)//movesPerDiagram+1
+ moveNumber=0
+
+ for i in range(diagramsNeeded):
+ # inicializuj diagram
+ diagram=Tikz()
+
+ for lineNumber,line in enumerate(game.board):
+ for itemNumber,item in enumerate(line):
+ if item==1: diagram.drawStone(itemNumber,lineNumber,"b")
+ if item==-1: diagram.drawStone(itemNumber,lineNumber,"w")
+ localBoard={(a,b):game.board[b][a]-1 for a in range(19) for b in range(19) if game.board[b][a]!=0}
+
+ for j in range(movesPerDiagram):
+ # kresli tahy
+ if moveNumber>=len(moves): break
+
+ c,(x,y)=moves[moveNumber]
+ c=c.lower()
+
+ if not game.move(1 if c=='b' else -1,x,y):
+ print("illegal move: {0} at {1},{2}".format(moveNumber+1,x,y))
+ moveNumber+=1
+ continue
+
+ # zapíšu tah na volný průsečík
+ if not (x,y) in localBoard:
+ localBoard[(x,y)]=moveNumber+1
+ diagram.drawMove(x,y,moveNumber+1,c)
+ # průsečík je obsazený nepopsaným kamenem
+ elif localBoard[(x,y)]<1:
+ # průsečík není popsaný ani písmenem
+ if not (x,y) in letters:
+ letters[(x,y)]=letter
+ color='b' if localBoard[(x,y)]==0 else 'w'
+ diagram.drawMove(x,y,letter,color)
+ letter=chr(ord(letter)+1)
+ overlays+="{0} = {1}\n".format(moveNumber+1,letters[(x,y)])
+ # průsečík je obsazený očíslovaným kamenem
+ else: overlays+="{0} = {1}\n".format(moveNumber+1,localBoard[(x,y)])
+
+ moveNumber+=1
+
+ # dokonči a ulož diagram
+ t=open("out/{0}-{1}.tex".format(shortName,i+1),'w') # nový soubor
+ t.write(diagram.getContent())
+ t.close()
+
+ notes=open("out/{0}.txt".format(shortName),'w')
+ notes.write(overlays)
+ notes.close()
+
+print("processing:")
+for item in files:
+ if os.path.isfile(item):
+ print("{0}... ".format("".join(item.split('/')[-1].split('.')[:-1])),end="")
+ processFile(item)
+ print("done")
+ elif os.path.isdir(item):
+ print("contents of the '{0}' directory added to the queue".format(item))
+ else: print("the '{0}' path could not be resolved to either a file nor a directory".format(item))