<reponame>vEnhance/dotfiles
#########
## TSQ ##
#########

import sys
import string
import argparse

fn_names = {
		'circumcenter' : 3,
		'orthocenter' : 3,
		'incircle' : 3,
		'circumcircle' : 3,
		'centroid' : 3,
		'incenter' : 3,
		'midpoint' : 1,
		'extension' : 4,
		'foot' : 3,
		'CP' : 2,
		'CR' : 2,
		'dir' : 1,
		'conj' : 1,
		'intersect': 2,
		'IP': 2,
		'OP': 2,
		'Line': 2,
		'bisectorpoint': 2,
		'arc': 4,
		'abs': 1,
		}
short_names = {
		'circle' : 'circumcircle',
		'rightangle' : 'rightanglemark',
		}
# The following is really bad
for letter in string.ascii_uppercase:
	fn_names['-%s+2*foot' %letter] = 3

def autoParen(tokens):
	if len(tokens) == 0: return ''
	else: t = tokens.pop(0)

	if t in short_names:
		t = short_names[t]
	if t in fn_names:
		nargs = fn_names[t]
		args = [autoParen(tokens) for i in range(nargs)]
		return t + '(' + ', '.join(args) + ')'
	else:
		return t


# argument parsing
parser = argparse.ArgumentParser(description='Generate a diagram.')
parser.add_argument('-p', '--pre',
		help = 'Adds an Asymptote preamble.',
		action = 'store_true',
		dest = 'preamble',
		default = False)
parser.add_argument('-t', '--terse',
		help = 'Omits the source code at the end',
		action = 'store_true',
		dest = 'terse',
		default = False)
parser.add_argument('-n', '--no-trans',
		help = 'Temporarily disables the transparencies.',
		action = 'store_true',
		dest = 'notrans',
		default = False)
parser.add_argument('fname',
		help = 'If provided, reads from the designated file rather than stdin',
		metavar = "filename",
		nargs = '?',
		default = '')
parser.add_argument('-s', '--size',
		help = 'If provided, sets the image size in the preamble. (Use with -p.)',
		action = 'store',
		dest = 'size',
		default = '8cm')
parser.add_argument('-f', '--fontsize',
		help = 'If provided, sets the image size in the preamble. (Use with -p.)',
		action = 'store',
		dest = 'fontsize',
		default = '9pt')
opts = parser.parse_args()


# Initialize some stuff
raw_code = ""
dot_code = ""

GENERIC_PREAMBLE = r'''
usepackage("amsmath");
usepackage("amssymb");
settings.tex="pdflatex";
settings.outformat="pdf";
// Replacement for olympiad+cse5 which is not standard
import geometry;
// recalibrate fill and filldraw for conics
void filldraw(picture pic = currentpicture, conic g, pen fillpen=defaultpen, pen drawpen=defaultpen)
	{ filldraw(pic, (path) g, fillpen, drawpen); }
void fill(picture pic = currentpicture, conic g, pen p=defaultpen)
	{ filldraw(pic, (path) g, p); }
// some geometry
pair foot(pair P, pair A, pair B) { return foot(triangle(A,B,P).VC); }
pair orthocenter(pair A, pair B, pair C) { return orthocentercenter(A,B,C); }
pair centroid(pair A, pair B, pair C) { return (A+B+C)/3; }
// cse5 abbrevations
path CP(pair P, pair A) { return circle(P, abs(A-P)); }
path CR(pair P, real r) { return circle(P, r); }
pair IP(path p, path q) { return intersectionpoints(p,q)[0]; }
pair OP(path p, path q) { return intersectionpoints(p,q)[1]; }
path Line(pair A, pair B, real a=0.6, real b=a) { return (a*(A-B)+A)--(b*(B-A)+B); }
'''.strip()

if opts.preamble:
	print("defaultpen(fontsize(%s));" % opts.fontsize)
	print("size(%s);" %opts.size)
	print(GENERIC_PREAMBLE)
if opts.fname != '':
	stream = open(opts.fname, 'r')
else:
	stream = sys.stdin


in_comment_mode = False
# Print output
for line in stream:
	line = line.strip()

	# Empty line = newspace
	if line == "":
		print("")
		raw_code += line + "\n"
		continue

	# Handling of comments
	if line[:2] == "//":
		print(line)
		raw_code += line + "\n"
		continue
	if line[:2] == "/*" and line.endswith("*/"):
		print(line)
		continue
	elif line[:2] == "/*":
		in_comment_mode = True
		print(line)
		continue
	elif in_comment_mode and line.endswith("*/"):
		in_comment_mode = False
		print("*/")
		continue
	if in_comment_mode:
		print(line)
		continue
	
	raw_code += line + "\n"

	# Verbatim
	if line[0] == "!":
		print(line[1:].strip())
		continue

	# Decide whether to auto-paren
	if line[0] == ".":
		# Force auto paren
		do_auto_paren = True
		line = line[1:].strip()
	elif line[0] == ">":
		do_auto_paren = False
		line = line[1:].strip()
	else:
		do_auto_paren = not (', ' in line) # just default to auto-ing unless , appears

	if "=" in line:
		raw_name, raw_expr = line.split("=", 2)
		if len(raw_name) > 0 and raw_name[-1] == ":":
			draw_point = False
			label_point = False
			raw_name = raw_name[:-1].strip()
		elif len(raw_name) > 0 and raw_name[-1] == ".":
			draw_point = True
			label_point = False
			raw_name = raw_name[:-1].strip()
		else:
			draw_point = True
			label_point = True
		raw_name = raw_name.strip()
		point_name = raw_name.replace("'", "p").replace("*", "s").replace("^", "") # name used in source code
		label_name = raw_name.replace("*", r"^\ast") # name passed to LaTeX label function

		if do_auto_paren:
			tokens = raw_expr.strip().split(' ')
			expr = autoParen(tokens)
			if len(tokens) == 0:
				direction = "dir(" + point_name + ")"
			elif len(tokens) == 1:
				magnitude, angle = tokens[0].split("R", 2)
				direction = "dir(" + angle + ")"
				if magnitude != "":
					direction = magnitude + "*" + direction
		else:
			expr = raw_expr.strip()
			direction = "dir(" + point_name + ")"

		if point_name != "":
			print("pair %s = %s;" %(point_name, expr))
		if draw_point:
			if label_point:
				dot_code += "dot(\"$%s$\", %s, %s);\n" %(label_name, point_name, direction)
			else:
				dot_code += "dot(%s);\n" %(point_name if point_name else expr)

	else:
		line = line.strip()
		pen = None
		if do_auto_paren:
			tokens = line.split(' ')
			expr = autoParen(tokens)
			# 0.2 mediumcyan / blue -> opacity(0.2)+mediumcyan, blue
			if '/' in tokens:
				tindex = tokens.index('/') # index of transparency divider
				if tokens[0][0] == "0": # first token is leading 0
					fillpen = "opacity(" + tokens[0] + ")"
					if tindex != 1:
						fillpen += '+' + '+'.join(tokens[1:tindex]) # add on others
				else:
					fillpen = '+'.join(tokens[0:tindex])
				drawpen = '+'.join(tokens[tindex+1:])
				if not drawpen: drawpen = "defaultpen"

				if opts.notrans:
					print("draw(" + expr + ", " + drawpen + ");")
				else:
					print("filldraw(" + expr + ", " + fillpen + ", " + drawpen + ");")
			else:
				pen = '+'.join(tokens) # any remaining tokens
		else:
			expr = line # you'll have to put commas here for pens manually
			pen = ''
			
		if pen:
			print("draw(" + expr + ", " + pen + ");")
		elif pen is not None:
			print("draw(" + expr + ");")

print("\n" + dot_code)
if opts.terse:
	print("/* Source generated by TSQ */")
else:
	print("/* TSQ Source:")
	print("")
	print(raw_code.strip())
	print("")
	print("*/")

stream.close()

#########
## TSQ ##
#########

import sys
import string
import argparse

fn_names = {
		'circumcenter' : 3,
		'orthocenter' : 3,
		'incircle' : 3,
		'circumcircle' : 3,
		'centroid' : 3,
		'incenter' : 3,
		'midpoint' : 1,
		'extension' : 4,
		'foot' : 3,
		'CP' : 2,
		'CR' : 2,
		'dir' : 1,
		'conj' : 1,
		'intersect': 2,
		'IP': 2,
		'OP': 2,
		'Line': 2,
		'bisectorpoint': 2,
		'arc': 4,
		'abs': 1,
		}
short_names = {
		'circle' : 'circumcircle',
		'rightangle' : 'rightanglemark',
		}
# The following is really bad
for letter in string.ascii_uppercase:
	fn_names['-%s+2*foot' %letter] = 3

def autoParen(tokens):
	if len(tokens) == 0: return ''
	else: t = tokens.pop(0)

	if t in short_names:
		t = short_names[t]
	if t in fn_names:
		nargs = fn_names[t]
		args = [autoParen(tokens) for i in range(nargs)]
		return t + '(' + ', '.join(args) + ')'
	else:
		return t


# argument parsing
parser = argparse.ArgumentParser(description='Generate a diagram.')
parser.add_argument('-p', '--pre',
		help = 'Adds an Asymptote preamble.',
		action = 'store_true',
		dest = 'preamble',
		default = False)
parser.add_argument('-t', '--terse',
		help = 'Omits the source code at the end',
		action = 'store_true',
		dest = 'terse',
		default = False)
parser.add_argument('-n', '--no-trans',
		help = 'Temporarily disables the transparencies.',
		action = 'store_true',
		dest = 'notrans',
		default = False)
parser.add_argument('fname',
		help = 'If provided, reads from the designated file rather than stdin',
		metavar = "filename",
		nargs = '?',
		default = '')
parser.add_argument('-s', '--size',
		help = 'If provided, sets the image size in the preamble. (Use with -p.)',
		action = 'store',
		dest = 'size',
		default = '8cm')
parser.add_argument('-f', '--fontsize',
		help = 'If provided, sets the image size in the preamble. (Use with -p.)',
		action = 'store',
		dest = 'fontsize',
		default = '9pt')
opts = parser.parse_args()


# Initialize some stuff
raw_code = ""
dot_code = ""

GENERIC_PREAMBLE = r'''
usepackage("amsmath");
usepackage("amssymb");
settings.tex="pdflatex";
settings.outformat="pdf";
// Replacement for olympiad+cse5 which is not standard
import geometry;
// recalibrate fill and filldraw for conics
void filldraw(picture pic = currentpicture, conic g, pen fillpen=defaultpen, pen drawpen=defaultpen)
	{ filldraw(pic, (path) g, fillpen, drawpen); }
void fill(picture pic = currentpicture, conic g, pen p=defaultpen)
	{ filldraw(pic, (path) g, p); }
// some geometry
pair foot(pair P, pair A, pair B) { return foot(triangle(A,B,P).VC); }
pair orthocenter(pair A, pair B, pair C) { return orthocentercenter(A,B,C); }
pair centroid(pair A, pair B, pair C) { return (A+B+C)/3; }
// cse5 abbrevations
path CP(pair P, pair A) { return circle(P, abs(A-P)); }
path CR(pair P, real r) { return circle(P, r); }
pair IP(path p, path q) { return intersectionpoints(p,q)[0]; }
pair OP(path p, path q) { return intersectionpoints(p,q)[1]; }
path Line(pair A, pair B, real a=0.6, real b=a) { return (a*(A-B)+A)--(b*(B-A)+B); }
'''.strip()

if opts.preamble:
	print("defaultpen(fontsize(%s));" % opts.fontsize)
	print("size(%s);" %opts.size)
	print(GENERIC_PREAMBLE)
if opts.fname != '':
	stream = open(opts.fname, 'r')
else:
	stream = sys.stdin


in_comment_mode = False
# Print output
for line in stream:
	line = line.strip()

	# Empty line = newspace
	if line == "":
		print("")
		raw_code += line + "\n"
		continue

	# Handling of comments
	if line[:2] == "//":
		print(line)
		raw_code += line + "\n"
		continue
	if line[:2] == "/*" and line.endswith("*/"):
		print(line)
		continue
	elif line[:2] == "/*":
		in_comment_mode = True
		print(line)
		continue
	elif in_comment_mode and line.endswith("*/"):
		in_comment_mode = False
		print("*/")
		continue
	if in_comment_mode:
		print(line)
		continue
	
	raw_code += line + "\n"

	# Verbatim
	if line[0] == "!":
		print(line[1:].strip())
		continue

	# Decide whether to auto-paren
	if line[0] == ".":
		# Force auto paren
		do_auto_paren = True
		line = line[1:].strip()
	elif line[0] == ">":
		do_auto_paren = False
		line = line[1:].strip()
	else:
		do_auto_paren = not (', ' in line) # just default to auto-ing unless , appears

	if "=" in line:
		raw_name, raw_expr = line.split("=", 2)
		if len(raw_name) > 0 and raw_name[-1] == ":":
			draw_point = False
			label_point = False
			raw_name = raw_name[:-1].strip()
		elif len(raw_name) > 0 and raw_name[-1] == ".":
			draw_point = True
			label_point = False
			raw_name = raw_name[:-1].strip()
		else:
			draw_point = True
			label_point = True
		raw_name = raw_name.strip()
		point_name = raw_name.replace("'", "p").replace("*", "s").replace("^", "") # name used in source code
		label_name = raw_name.replace("*", r"^\ast") # name passed to LaTeX label function

		if do_auto_paren:
			tokens = raw_expr.strip().split(' ')
			expr = autoParen(tokens)
			if len(tokens) == 0:
				direction = "dir(" + point_name + ")"
			elif len(tokens) == 1:
				magnitude, angle = tokens[0].split("R", 2)
				direction = "dir(" + angle + ")"
				if magnitude != "":
					direction = magnitude + "*" + direction
		else:
			expr = raw_expr.strip()
			direction = "dir(" + point_name + ")"

		if point_name != "":
			print("pair %s = %s;" %(point_name, expr))
		if draw_point:
			if label_point:
				dot_code += "dot(\"$%s$\", %s, %s);\n" %(label_name, point_name, direction)
			else:
				dot_code += "dot(%s);\n" %(point_name if point_name else expr)

	else:
		line = line.strip()
		pen = None
		if do_auto_paren:
			tokens = line.split(' ')
			expr = autoParen(tokens)
			# 0.2 mediumcyan / blue -> opacity(0.2)+mediumcyan, blue
			if '/' in tokens:
				tindex = tokens.index('/') # index of transparency divider
				if tokens[0][0] == "0": # first token is leading 0
					fillpen = "opacity(" + tokens[0] + ")"
					if tindex != 1:
						fillpen += '+' + '+'.join(tokens[1:tindex]) # add on others
				else:
					fillpen = '+'.join(tokens[0:tindex])
				drawpen = '+'.join(tokens[tindex+1:])
				if not drawpen: drawpen = "defaultpen"

				if opts.notrans:
					print("draw(" + expr + ", " + drawpen + ");")
				else:
					print("filldraw(" + expr + ", " + fillpen + ", " + drawpen + ");")
			else:
				pen = '+'.join(tokens) # any remaining tokens
		else:
			expr = line # you'll have to put commas here for pens manually
			pen = ''
			
		if pen:
			print("draw(" + expr + ", " + pen + ");")
		elif pen is not None:
			print("draw(" + expr + ");")

print("\n" + dot_code)
if opts.terse:
	print("/* Source generated by TSQ */")
else:
	print("/* TSQ Source:")
	print("")
	print(raw_code.strip())
	print("")
	print("*/")

stream.close()
######### ## TSQ ## ######### # The following is really bad # argument parsing # Initialize some stuff usepackage("amsmath"); usepackage("amssymb"); settings.tex="pdflatex"; settings.outformat="pdf"; // Replacement for olympiad+cse5 which is not standard import geometry; // recalibrate fill and filldraw for conics void filldraw(picture pic = currentpicture, conic g, pen fillpen=defaultpen, pen drawpen=defaultpen) 	{ filldraw(pic, (path) g, fillpen, drawpen); } void fill(picture pic = currentpicture, conic g, pen p=defaultpen) 	{ filldraw(pic, (path) g, p); } // some geometry pair foot(pair P, pair A, pair B) { return foot(triangle(A,B,P).VC); } pair orthocenter(pair A, pair B, pair C) { return orthocentercenter(A,B,C); } pair centroid(pair A, pair B, pair C) { return (A+B+C)/3; } // cse5 abbrevations path CP(pair P, pair A) { return circle(P, abs(A-P)); } path CR(pair P, real r) { return circle(P, r); } pair IP(path p, path q) { return intersectionpoints(p,q)[0]; } pair OP(path p, path q) { return intersectionpoints(p,q)[1]; } path Line(pair A, pair B, real a=0.6, real b=a) { return (a*(A-B)+A)--(b*(B-A)+B); } # Print output # Empty line = newspace # Handling of comments # Verbatim # Decide whether to auto-paren # Force auto paren # just default to auto-ing unless , appears # name used in source code # name passed to LaTeX label function # 0.2 mediumcyan / blue -> opacity(0.2)+mediumcyan, blue # index of transparency divider # first token is leading 0 # add on others # any remaining tokens # you'll have to put commas here for pens manually