diff --git a/.gitignore b/.gitignore index a6afdce..f430683 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,7 @@ *.sgf *.tex +*.aux +*.dvi +*.log +*.ps +*.pdf diff --git a/kifugen.py b/kifugen.py index 990aa5b..11f2fc6 100644 --- a/kifugen.py +++ b/kifugen.py @@ -1,7 +1,7 @@ -import sys -import os -import subprocess import argparse +import os +import sys +from subprocess import check_call, DEVNULL, STDOUT, CalledProcessError parser = argparse.ArgumentParser(description='Convert sgf go records into a kifu format.') @@ -13,6 +13,7 @@ parser.add_argument('-o', "--open", action="store_true", dest="o", default=False args = parser.parse_args(sys.argv[1:]) filePath = args.sgfFile +fileBase = ".".join(filePath.split(".")[:-1]) splitBoardAt = [x for x in range(0, 400, args.step)] with open(filePath, 'r') as myfile: @@ -23,7 +24,7 @@ header = sgfData[0] moves = sgfData[1:] def get_tag_from_header(tag): - eventIdxStart = header.lower().find(tag.lower() + "[") + eventIdxStart = header.lower().find(f"{tag.lower()}[") eventIdxEnd = -1 if eventIdxStart != -1 : @@ -31,115 +32,127 @@ def get_tag_from_header(tag): return header[len(tag) + 1 + eventIdxStart:eventIdxEnd] return "" -def extractCoordinatesFromMove(move): +def extract_coordinates(move): try: firstCoordinate = move[2] secondCoordinate = ord(move[3])-96 + # mirror at x axis so it looks normal + secondCoordinate = parsedHeader["boardSize"] - secondCoordinate + 1 if ord(move[2]) >= ord("i"): firstCoordinate = chr(ord(firstCoordinate) + 1) return firstCoordinate, secondCoordinate except IndexError: + # wierd move return -1,-1 -def generateTitle(): - out = "" +def generate_title(): + out = [] if parsedHeader["event"] != "": - out+=parsedHeader["event"] + "\\\\" - out += parsedHeader["playerBlack"] + out.extend([parsedHeader["event"], "\\\\"]) + out.append(parsedHeader["playerBlack"]) if parsedHeader["rankBlack"] != "": - out += "[" + parsedHeader["rankBlack"] + "]" - out += " - " + parsedHeader["playerWhite"] + out.extend(["[", parsedHeader["rankBlack"], "]"]) + out.extend([" - ", parsedHeader["playerWhite"]]) if parsedHeader["rankWhite"] != "": - out += "[" + parsedHeader["rankWhite"] + "]" + out.extend(["[", parsedHeader["rankWhite"], "]"]) + + return "".join(out) + +def generate_moves(): + finished = False + outText = [] + for i in range(len(splitBoardAt)-1): + currentSplit = splitBoardAt[i] + nextSplit = splitBoardAt[i+1] + + outText.extend(["\n\\setcounter{gomove}{0}\n", "\\begin{psgoboard}\n\t"]) + + # old moves + for j in range(currentSplit): + firstCoordinate, secondCoordinate = extract_coordinates(moves[j]) + if not (firstCoordinate == -1 or secondCoordinate == -1): + outText.append(f"\\move*{{{firstCoordinate}}}{{{secondCoordinate}}} ") + if j % 5 == 4: + outText.append("\n\t") + elif secondCoordinate < 10: # nice spacing + outText.append(" ") + + # new moves + for j in range(nextSplit-currentSplit): + firstCoordinate, secondCoordinate = extract_coordinates(moves[currentSplit+j]) + if not (firstCoordinate == -1 or secondCoordinate == -1): + outText.append(f"\\move{{{firstCoordinate}}}{{{secondCoordinate}}} ") + if j % 5 == 4: + outText.append("\n\t") + elif secondCoordinate < 10: # nice spacing + outText.append(" ") + + # was it the last move? + if currentSplit+j == len(moves)-1: + finished = True + break + + outText.append("\n\\end{psgoboard}\n") + if finished: + break - return out + return "".join(outText) parsedHeader = { - "event" : get_tag_from_header("EV"), - "gameName" : get_tag_from_header("GN"), - "date" : get_tag_from_header("RD"), - "boardSize" : int(get_tag_from_header("SZ")), + "event" : get_tag_from_header("EV"), + "gameName" : get_tag_from_header("GN"), + "date" : get_tag_from_header("RD"), + "boardSize" : int(get_tag_from_header("SZ")), "playerBlack" : get_tag_from_header("PB"), "playerWhite" : get_tag_from_header("PW"), - "rankBlack" : get_tag_from_header("BR"), - "rankWhite" : get_tag_from_header("WR"), - "komi" : get_tag_from_header("KM"), - "result" : get_tag_from_header("RE") + "rankBlack" : get_tag_from_header("BR"), + "rankWhite" : get_tag_from_header("WR"), + "komi" : get_tag_from_header("KM"), + "result" : get_tag_from_header("RE") } -outText = """ -\\documentclass[a4paper]{article} -\\usepackage{psgo} -\\usepackage[ngerman]{babel} -\\usepackage[margin=2cm,nohead]{geometry} -\\setgounit{0.5cm} +title = generate_title() +date = parsedHeader["date"] +moves = generate_moves() +result = parsedHeader["result"] + +outText = f""" +\\documentclass[a4paper]{{article}} +\\usepackage{{psgo}} +\\usepackage[ngerman]{{babel}} +\\usepackage[margin=2cm,nohead]{{geometry}} -\\author{} -\\title{%s} -\\date{%s} +\\setgounit{{0.5cm}} -\\begin{document} +\\author{{}} +\\title{{{title}}} +\\date{{{date}}} + +\\begin{{document}} \\maketitle -\\vspace{3.5cm} -\\begin{center} -""" % (generateTitle(), parsedHeader["date"]) - -finished = False -for i in range(len(splitBoardAt)-1): - currentSplit = splitBoardAt[i] - nextSplit = splitBoardAt[i+1] - - outText += "\n\\setcounter{gomove}{0}\n" - outText += "\\begin{psgoboard}\n\t" - - # old moves - for j in range(currentSplit): - firstCoordinate, secondCoordinate = extractCoordinatesFromMove(moves[j]) - outText += "\\move*{%s}{%d} " % (firstCoordinate, parsedHeader["boardSize"] - secondCoordinate + 1) - if j % 5 == 4: - outText += "\n\t" - elif parsedHeader["boardSize"] - secondCoordinate < 9: # nice spacing - outText += " " - - # new moves - for j in range(nextSplit-currentSplit): - firstCoordinate, secondCoordinate = extractCoordinatesFromMove(moves[currentSplit+j]) - if not (firstCoordinate == -1 or secondCoordinate == -1): - outText += "\\move{%s}{%d} " % (firstCoordinate, parsedHeader["boardSize"] - secondCoordinate + 1) - if j % 5 == 4: - outText += "\n\t" - elif parsedHeader["boardSize"] - secondCoordinate < 9: # nice spacing - outText += " " - - # was it the last move? - if currentSplit+j == len(moves)-1: - finished = True - break +\\vspace{{3.5cm}} +\\begin{{center}} - outText += "\n\\end{psgoboard}\n" - if finished: - break +{moves} -outText += """ -\\textbf{%s} +\\textbf{{{result}}} -\\end{center} -\\end{document} -""" % parsedHeader["result"] +\\end{{center}} +\\end{{document}} +""" -outFileBaseName = ".".join(filePath.split(".")[:-1]) -with open(outFileBaseName+ ".tex", 'w') as outFile: +with open(f"{fileBase}.tex", 'w') as outFile: outFile.write(outText) # should be compiled to pdf? if args.c: try: - subprocess.check_call(['latex', outFileBaseName + ".tex"], stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT) - subprocess.check_call(['dvips', "-P", "pdf", outFileBaseName + ".dvi"], stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT) - subprocess.check_call(['ps2pdf', outFileBaseName + ".ps"], stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT) - except subprocess.CalledProcessError: + check_call(['latex', f"{fileBase}.tex"], stdout=DEVNULL, stderr=STDOUT) + check_call(['dvips', f"{fileBase}.dvi", "-P", "pdf"], stdout=DEVNULL, stderr=STDOUT) + check_call(['ps2pdf', f"{fileBase}.ps"], stdout=DEVNULL, stderr=STDOUT) + except CalledProcessError: print("error") else: if args.o: - os.system('"%s.pdf"' % outFileBaseName) + os.system(f'"{fileBase}.pdf"')