#!/usr/bin/python
""" $Id: XMLWriter.py,v 1.4 2001/12/20 15:36:47 connolly Exp $
A Sax Handler for writing XML tags, attributes, and data characters.
"""

import re

#cf  Python/XML HOWTO
# The Python/XML Special Interest Group
# xml-sig@python.org 
# (edited by akuchling@acm.org)
# http://www.python.org/doc/howto/xml/xml-howto.html
#
#cf debian python-xml 0.5.1-5 (release date?)
from xml.sax.saxlib import DocumentHandler


class T(DocumentHandler):
    """
    taken from
    Id: notation3.py,v 1.10 2000/10/17 01:08:36 connolly Exp 
    which was taken previously from
    Id: tsv2xml.py,v 1.1 2000/10/02 19:41:02 connolly Exp connolly
    """

    def __init__(self, outFp):
	self._outFp = outFp
	self._elts = []
	self._empty = 0 # just wrote start tag, think it's an empty element.

    #@@ on __del__, close all open elements?

    def startElement(self, n, attrs):
	o = self._outFp

	if self._empty: o.write("  >")

	o.write("<%s" % (n,))

	self._attrs(attrs)

	self._elts.append(n)

	o.write("\n%s" % ('  ' * (len(self._elts)-1) ))
	self._empty = 1

    def _attrs(self, attrs):
	o = self._outFp

	for i in range(attrs.getLength()):
	    n = attrs.getName(i)
	    v = attrs.getValue(i)
	    #@@BUG: need to escape markup chars in v
	    o.write("\n%s%s=\"%s\"" \
		    % ((' ' * (len(self._elts) * 2 + 3) ),
		       n, v))

    def endElement(self, name=None):
	n = self._elts[-1]
	# @@ assert n= name?
	del self._elts[-1]

	o = self._outFp

	if self._empty:
	    o.write("/>")
	    self._empty = 0
	else:
	    o.write("</%s\n%s>" % (n, ('  ' * len(self._elts) )))

    markupChar = re.compile(r"[\n\r<>&\177-\377]")

    def characters(self, ch, start=0, length=-1):
	#@@ throw an exception if the element stack is empty
	o = self._outFp

	if self._empty:
	    o.write("  >")
	    self._empty = 0

	if length<0: length = len(ch)
	else: length = start+length

	i = start
	while i < length:
	    m = self.markupChar.search(ch, i)
	    if not m:
		o.write(ch[i:])
		break
	    j = m.start()
	    o.write(ch[i:j])
	    o.write("&#%d;" % (ord(ch[j]),))
	    i = j + 1


from XMLAttrs import Attrs

def test():
    import sys
    xwr = T(sys.stdout)

    xwr.startElement('abc', Attrs())
    xwr.startElement('def', Attrs((('x', '1'), ('y', '0'))))
    xwr.startElement('ghi', Attrs())
    xwr.endElement('ghi')
    xwr.characters("abcdef")
    xwr.endElement('def')
    xwr.endElement('abc')

if __name__ == '__main__': test()
