# -*- coding: latin-1 -*-
""" 
   Copyright (C) 2005 PimenTech SARL (http://www.pimentech.net)

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public License as
   published by the Free Software Foundation; either version 2 of the
   License, or (at your option) any later version.

   This library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Library General Public License for more details.

   You should have received a copy of the GNU Library General Public
   License along with this library; see the file COPYING.LIB.  If not,
   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.  
"""

__version__='$Revision: 1.10 $'[11:-2]

from string import *
from object import *
import htmlentitydefs
import re

class XmlWriter(Object):
	
	def __init__(self, id, title=''):
		Object.__init__(self, id, title)

		self.output = None
		
		self.encoding = 'utf-8'
		
		# this pattern matches substrings of reserved and non-ASCII characters
		self.pattern = re.compile(r"[&<>\"'\x00-\x20]+")
		#self.pattern = re.compile(r"[\x80-\xff]+")

		# create character map
		self.entity_map = {}

		for i in range(32):
			self.entity_map[chr(i)] = ''
		for i in range(32,256):
			self.entity_map[chr(i)] = chr(i)
			
		self.entity_map["'"] = "&apos;"
		self.entity_map[chr(9)] = chr(9)
		self.entity_map['\n'] = '\n'
		self.entity_map['\r'] = '\r'
		
		for entity, char in htmlentitydefs.entitydefs.items():
			if self.entity_map.has_key(char):
				self.entity_map[char] = "&%s;" % entity

	def write_start_document(self, dtd = None):
		self.output.write('<?xml version="1.0" encoding="%s"?>\n' % self.encoding)
		if dtd:
			self.output.write('<!DOCTYPE LOT SYSTEM "%s">\n' % dtd)
			
	def write_end_document(self):
		return
		
	def _write_start_element(self, name, options = [], close = 0):
		self.output.write('<%s' % name)
		for (key, value) in options:
			if value:
				self.output.write(' %s="%s"' % (key, self.escape_html(('%s' % value))))
			else:
				self.output.write(' %s=""' % key)
		if close:
			self.output.write('/>')
		else:
			self.output.write('>')
			
	def write_start_element(self, name, options = [], close = 0):
		self._write_start_element(name, options, close)
		self.output.write('\n')
		
	def write_end_element(self, name):
		self.output.write('</%s>\n' % name)

	def write_characters(self, data):
		if data or data == 0:
			self.output.write(self.escape_html(('%s' % data).encode(self.encoding)))

	def write_element(self, name, data = None, options = []):

		if data or data == 0:
			self._write_start_element(name, options)
		else:
			if options:
				self.write_start_element(name, options, 1)
			return

		self.write_characters(data)
		self.write_end_element(name)
		
	def escape_entity(self, m):
		return join(map(self.entity_map.get, m.group()), "")

	def escape_html(self, string):
		return self.pattern.sub(self.escape_entity, string)

