#! /usr/bin/env python


"""This script builds the Lib/fontTools/ttLib/tables/otData.py file
from the OpenType HTML documentation. However, it depends on a slightly
patched version the the HTML, as there are some inconsistencies in the
markup and the naming of certain fields. See doco.diff for differences,
but this is probably against a slightly older version of the documentation
than what is currently online. The documentation was taken from this URL:
	http://www.microsoft.com/typography/otspec/default.htm
"""


from sgmllib import SGMLParser


class HTMLParser(SGMLParser):
	
	def __init__(self):
		SGMLParser.__init__(self)
		self.data = None
		self.currenttable = None
		self.lastcaption = None
	
	def handle_data(self, data):
		if self.data is not None:
			self.data.append(data)
	
	def start_i(self, attrs):
		if self.currenttable is None:
			self.data = []
	def end_i(self):
		if self.currenttable is None:
			self.lastcaption = " ".join(self.data)
			self.data = None
	
	def start_b(self, attrs):
		if self.currenttable is None:
			self.data = []
	def end_b(self):
		if self.currenttable is None:
			self.lastcaption = " ".join(self.data)
			self.data = None
	
	def start_table(self, attrs):
		attrs = dict(attrs)
		if attrs.get('width') in ('455', '460'):
			#print "---", attrs
			self.currenttable = []
		else:
			self.currenttable = None
	def end_table(self):
		if self.currenttable is not None and self.lastcaption is not None:
			if self.currenttable[0] == ['Type', 'Name', 'Description'] or \
					self.currenttable[0] == ['Value', 'Type', 'Description']:
				caption = self.lastcaption.split()
				name = caption[0]
				if name == "LookupType" or name == "LookupFlag":
					self.currenttable = None
					return
				elif name == "Device":
					if "Tables" in caption:
						# XXX skip this one
						self.currenttable = None
						return
				buildTable(name, self.currenttable[1:], self.lastcaption)
		self.currenttable = None
	
	def start_tr(self, attrs):
		if self.currenttable is not None:
			self.currenttable.append([])
	def end_tr(self):
		pass
	
	def start_td(self, attrs):
		self.data = []
	def end_td(self):
		if self.currenttable is not None and self.data is not None:
			self.currenttable[-1].append(" ".join(self.data))
			self.data = None


globalDups = {}
localDups = {}
not3 = []

def buildTable(name, table, caption):
	if globalDups.has_key(name):
		globalDups[name].append(caption)
	else:
		globalDups[name] = [caption]
	print "\t(%s, [" % repr(name)
	allFields = {}
	for row in table:
		row = [" ".join(x.split()) for x in row]
		if len(row) <> 3:
			not3.append(row)
		row = makeRow(row)
		fieldName = row[1]
		if allFields.has_key(fieldName):
			key = (name, fieldName)
			localDups[key] = 1
		allFields[fieldName] = 1
		print "\t\t%s," % (tuple(row),)
	print "\t]),"
	print


def makeRow(rawRow):
	tp, name = rawRow[:2]
	name = name.strip()
	rest = tuple(rawRow[2:])
	if '[' in name:
		name, repeat = name.split("[")
		name = name.strip()
		assert repeat[-1] == "]"
		repeat = repeat[:-1].split()
		if repeat[1:]:
			repeatOffset = int("".join(repeat[1:]))
		else:
			repeatOffset = 0
		if not repeat:
			repeat = ""
		else:
			repeat = repeat[0]
	else:
		repeat = None
		repeatOffset = None
	row = (tp, name, repeat, repeatOffset) + rest
	return row


if __name__ == "__main__":
	import sys, os
	if "-" not in sys.argv:
		sys.stdout = open("otData.py", "w")
	print "otData = ["
	for file in ["chapter2.htm", "gpos.htm", "gsub.htm", "gdef.htm", "base.htm", "jstf.htm"]:
		name = os.path.splitext(file)[0]
		if name == "chapter2":
			name = "common"
		print
		print "\t#"
		print "\t# %s (generated from %s)" % (name, file)
		print "\t#"
		print 
		p = HTMLParser()
		p.feed(open(file).read())
		p.close()
	print "]"
	print
	for k, v in globalDups.items():
		if len(v) > 1:
			print "# XXX duplicate table name:", k, v
	for (name, fieldName), v in localDups.items():
		print "# XXX duplicate field name '%s' in table '%s'" % (fieldName, name)
	for n in not3:
		print "#XXX", not3
