"""Pattern matching inspired by Rexx. Version 0.1.
"""

import string

ParseError = "ParseError: Template does not comply with string."

def parse(text, template):
	""" rexxparse.parse(text, template)
		Parses a string according to a template and returns a dict with keys from
		the template. The parse functions is case insensitive.

		Templates are sequences of strings where odd numbered elements are
		keynames and even numbered elements are strings to be matched.

		All matches except the one for the last key are non-greedy. The first
		matching text need not appear at the start of a line.

		For instance
			parse('Joe Smith: Programmer',
				  ('', 'name1', ' ', 'name2',  ': ', 'vocation'))
		will return
			{'name1': 'Joe', 'vocation': 'Programmer', 'name2': 'Smith'}
	"""
	result = {}
	TEXT = string.upper(text)
	try:
		last_in_template = len(template)-1
		penultimate_in_template = last_in_template-1
		first = string.index(TEXT, string.upper(template[0]))+len(template[0])
		for i in range(1, len(template)+1, 2):
			if i == last_in_template:
				result[template[i]] = text[first:]
				return result
			else:
				if i == penultimate_in_template:
					newfirst = string.rindex(TEXT, string.upper(template[i+1]),
						first)
					result[template[i]] = text[first:newfirst]
					return result
				newfirst = string.index(TEXT, string.upper(template[i+1]),
					first)
				result[template[i]] = text[first:newfirst]
				first = newfirst + len(template[i+1])
	except:
		raise ParseError

def Parse(text, template):
	"""rexxparse.Parse(text, template)
		As rexxparse.parse, but case sensitive. Slightly faster.
	"""
	result = {}
	try:
		last_in_template = len(template)-1
		penultimate_in_template = last_in_template-1
		first = string.index(text, template[0])+len(template[0])
		for i in range(1, len(template)+1, 2):
			if i == last_in_template:
				result[template[i]] = text[first:]
				return result
			else:
				if i == penultimate_in_template:
					newfirst = string.rindex(text, template[i+1],
						first)
					result[template[i]] = text[first:newfirst]
					return result
				newfirst = string.index(text, template[i+1],
					first)
				result[template[i]] = text[first:newfirst]
				first = newfirst + len(template[i+1])
	except:
		raise ParseError

def template(metatemplate, delimiter='|'):
	"""rexxparse.template(metatemplate, delimiter)
		Both metatemplate and delimiter are strings. Keynames start with the
		delimiting character.  For instance, to generate the template used above:
			template('|name1| |name2|: |vocation', '|')
		will return
			('', 'name1', ' ', 'name2', ': ', 'vocation')
		
		Default delimiter is pipe (|).

		At the moment this is simply a stupid wrapper around string.split, but is
		included here for better readability.
	"""
	return string.split(metatemplate, delimiter)
