#!/usr/bin/env python
import sys
import string
import xmllib

class TranslatableStringParser(xmllib.XMLParser):
	def __init__(self):
		xmllib.XMLParser.__init__(self)
		self.filename = None
		self.strings = {}
		self.data = ""
	def add_string(self, string):
		if string == "":
			return
		if self.strings.has_key(string):
			self.strings[string].append((self.filename,
						     self.lineno))
		else:
			self.strings[string] = [(self.filename, self.lineno)]

	def read_file(self, filename):
		self.reset()
		self.filename = filename
		fp = open(filename, "r")
		data = fp.read(8192)
		while data:
			self.feed(data)
			data = fp.read(8192)
		fp.close()

	def syntax_error(self, message):
		sys.stderr.write("%s:%d: %s\n" % (self.filename, self.lineno,
						  message))
		sys.exit(1)

	def unknown_starttag(self, tag, attrs):
		self.data = ""
	def handle_data(self, data):
		self.data = self.data + data

	def translate_this_string(self):
		self.add_string(self.data)

	# this list should include all tags for which translation should occur
	end_label        = translate_this_string
	end_title        = translate_this_string
	end_text         = translate_this_string
	end_format       = translate_this_string
	end_copyright    = translate_this_string
	end_comments     = translate_this_string
	end_preview_text = translate_this_string
	end_tooltip      = translate_this_string
	def end_items(self):
		for item in string.split(self.data, '\n'):
			self.add_string(item)

	def output_pot(self, filename):
		strings = self.strings.keys()
		strings.sort()
		fp = open(filename, "w")
		fp.write('# SOME DESCRIPTIVE TITLE\n')
		for str in strings:
			pos = map(lambda x: "%s:%d" % x, self.strings[str])
			length = 80
			for p in pos:
				if length + len(p) > 74:
					fp.write('\n#:')
					length = 2
				fp.write(' ')
				fp.write(p)
				length = length + 1 + len(p)
			fp.write('\n')
			if '\n' in str:
				fp.write('msgid ""\n')
				lines = string.split(str, '\n')
				lines = map(lambda x:
					    '"%s\\n"\n' % (x,),
					    lines[:-1]) + \
					    ['"%s"\n' % (lines[-1],)]
				fp.writelines(lines)
			else:
				fp.write('msgid "%s"\n' % (str,))
			fp.write('msgstr ""\n')

	def output_c(self, filename):
		strings = self.strings.keys()
		strings.sort()
		fp = open(filename, "w")
		fp.write('/* SOME DESCRIPTIVE TITLE */\n')
		fp.write('/* This file is intended to be parsed by xgettext.\n')
		fp.write(' * It is not intended to be compiled.\n')
		fp.write(' */\n\n')
		fp.write('#if 0\n')
		fp.write('void some_function_name() {\n')
		for str in strings:
			pos = map(lambda x: "%s:%d" % x, self.strings[str])
			fp.write('\n  /*')
			length = 4
			for p in pos:
				if length + len(p) > 74:
					fp.write('\n   *')
					length = 4
				fp.write(' ')
				fp.write(p)
				length = length + 1 + len(p)
			fp.write(' */\n')
			if '\n' in str:
				fp.write('  _(""\n')
				lines = string.split(str, '\n')
				lines = map(lambda x:
					    '    "%s\\n"\n' % (x,),
					    lines[:-1]) + \
					    ['    "%s");\n' % (lines[-1],)]
				fp.writelines(lines)
			else:
				fp.write('  _("%s");\n' % (str,))
		fp.write('}\n')
		fp.write('#endif\n')

if __name__ == '__main__':
	import getopt

	options, args = getopt.getopt(sys.argv[1:], "cpo:vh",
				      ["c", "pot", "output=","version","help"])
	output = ''
	format = None
	for opt, optarg in options:
		if opt in ('-v', '--version'):
			print "libglade xgettext 0.0"
			sys.exit(0)
		if opt in ('-h', '--help'):
			print "Usage: libglade-xgettext [-c] [-p] [-o FILE] GLADEFILES"
			print ""
			print " -c, --c            Force C output format"
			print " -p, --pot          Force POT output format"
			print " -o, --output=FILE  Output file name"
			print " GLADEFILES         Glade XML input files"
			print ""
			print "This application creates a file of strings to be translated."
			print "It can output either a standard POT file (the default) or"
			print "output a C file that can be parsed by xgettext.  The C output"
			print "is implicitly turned on if the output filename ends in .c"
			sys.exit(0)
		if opt in ('-c', '--c'):
			format = "C"
		elif opt in ('-p', '--pot'):
			format = "pot"
		elif opt in ('-o', '--output'):
			output = optarg
	if not format:
		if len(output) > 2 and output[-2:] == '.c':
			format = "C"
		else:
			format = "pot"
	if not output:
		output = "/dev/stdout"
	if not args:
		sys.stderr.write("No input files given.\n")
		sys.exit(1)
	p = TranslatableStringParser()
	for file in args:
		p.read_file(file)
	if format == 'C':
		p.output_c(output)
	else:
		p.output_pot(output)
