text: from fontTools.misc.py23 import *
  from fontTools import ttLib
  from fontTools.misc.textTools import safeEval
  from fontTools.ttLib.tables.DefaultTable import DefaultTable
  import sys
  import os
  import logging
  
  
  log = logging.getLogger(__name__)
  
  class TTXParseError(Exception): pass
  
  BUFSIZE = 0x4000
  
  
  class XMLReader(object):
  
  	def __init__(self, fileOrPath, ttFont, progress=None, quiet=None, contentOnly=False):
  		if fileOrPath == '-':
  			fileOrPath = sys.stdin
  		if not hasattr(fileOrPath, "read"):
  			self.file = open(fileOrPath, "rb")
  			self._closeStream = True
  		else:
  			# assume readable file object
  			self.file = fileOrPath
  			self._closeStream = False
  		self.ttFont = ttFont
  		self.progress = progress
  		if quiet is not None:
  			from fontTools.misc.loggingTools import deprecateArgument
  			deprecateArgument("quiet", "configure logging instead")
  			self.quiet = quiet
  		self.root = None
  		self.contentStack = []
  		self.contentOnly = contentOnly
  		self.stackSize = 0
  
  	def read(self, rootless=False):
  		if rootless:
  			self.stackSize += 1
  		if self.progress:
  			self.file.seek(0, 2)
  			fileSize = self.file.tell()
  			self.progress.set(0, fileSize // 100 or 1)
  			self.file.seek(0)
  		self._parseFile(self.file)
  		if self._closeStream:
  			self.close()
  		if rootless:
  			self.stackSize -= 1
  
  	def close(self):
  		self.file.close()
  
  	def _parseFile(self, file):
  		from xml.parsers.expat import ParserCreate
  		parser = ParserCreate()
  		parser.StartElementHandler = self._startElementHandler
  		parser.EndElementHandler = self._endElementHandler
  		parser.CharacterDataHandler = self._characterDataHandler
  
  		pos = 0
  		while True:
  			chunk = file.read(BUFSIZE)
  			if not chunk:
  				parser.Parse(chunk, 1)
  				break
  			pos = pos + len(chunk)
  			if self.progress:
  				self.progress.set(pos // 100)
  			parser.Parse(chunk, 0)
  
  	def _startElementHandler(self, name, attrs):
  		if self.stackSize == 1 and self.contentOnly:
  			# We already know the table we're parsing, skip
  			# parsing the table tag and continue to
  			# stack '2' which begins parsing content
  			self.contentStack.append([])
  			self.stackSize = 2
  			return
  		stackSize = self.stackSize
  		self.stackSize = stackSize + 1
  		subFile = attrs.get("src")
  		if subFile is not None:
  			if hasattr(self.file, 'name'):
  				# if file has a name, get its parent directory
  				dirname = os.path.dirname(self.file.name)
  			else:
  				# else fall back to using the current working directory
  				dirname = os.getcwd()
  			subFile = os.path.join(dirname, subFile)
  		if not stackSize:
  			if name != "ttFont":
  				raise TTXParseError("illegal root tag: %s" % name)
  			sfntVersion = attrs.get("sfntVersion")
  			if sfntVersion is not None:
  				if len(sfntVersion) != 4:
  					sfntVersion = safeEval('"' + sfntVersion + '"')
  				self.ttFont.sfntVersion = sfntVersion
  			self.contentStack.append([])
  		elif stackSize == 1:
  			if subFile is not None:
  				subReader = XMLReader(subFile, self.ttFont, self.progress)
  				subReader.read()
  				self.contentStack.append([])
  				return
  			tag = ttLib.xmlToTag(name)
  			msg = "Parsing '%s' table..." % tag
  			if self.progress:
  				self.progress.setLabel(msg)
  			log.info(msg)
  			if tag == "GlyphOrder":
  				tableClass = ttLib.GlyphOrder
  			elif "ERROR" in attrs or ('raw' in attrs and safeEval(attrs['raw'])):
  				tableClass = DefaultTable
  			else:
  				tableClass = ttLib.getTableClass(tag)
  				if tableClass is None:
  					tableClass = DefaultTable
  			if tag == 'loca' and tag in self.ttFont:
  				# Special-case the 'loca' table as we need the
  				#    original if the 'glyf' table isn't recompiled.
  				self.currentTable = self.ttFont[tag]
  			else:
  				self.currentTable = tableClass(tag)
  				self.ttFont[tag] = self.currentTable
  			self.contentStack.append([])
  		elif stackSize == 2 and subFile is not None:
  			subReader = XMLReader(subFile, self.ttFont, self.progress, contentOnly=True)
  			subReader.read()
  			self.contentStack.append([])
  			self.root = subReader.root
  		elif stackSize == 2:
  			self.contentStack.append([])
  			self.root = (name, attrs, self.contentStack[-1])
  		else:
  			l = []
  			self.contentStack[-1].append((name, attrs, l))
  			self.contentStack.append(l)
  
  	def _characterDataHandler(self, data):
  		if self.stackSize > 1:
  			self.contentStack[-1].append(data)
  
  	def _endElementHandler(self, name):
  		self.stackSize = self.stackSize - 1
  		del self.contentStack[-1]
  		if not self.contentOnly:
  			if self.stackSize == 1:
  				self.root = None
  			elif self.stackSize == 2:
  				name, attrs, content = self.root
  				self.currentTable.fromXML(name, attrs, content, self.ttFont)
  				self.root = None
  
  
  class ProgressPrinter(object):
  
  	def __init__(self, title, maxval=100):
  		print(title)
  
  	def set(self, val, maxval=None):
  		pass
  
  	def increment(self, val=1):
  		pass
  
  	def setLabel(self, text):
  		print(text)
  