"""Preprocessor Highlight ShellExample."""
from trac.util import escape
import re

regex_crlf = re.compile("(\\r\\n|\\r|\\n)")
regexp_db_qstr = '"[^"\\\\]*(?:\\\\.[^"\\\\]*){0,250}"';
regexp_si_qstr = '\'[^\'\\\\]*(?:\\\\.[^\'\\\\]*){0,250}\'';
regexp = re.compile(
		('^(?P<path>[^ ]+.*)?(?P<cli>[#$]|&gt; )(?P<input>(?:[^\\\\\n\'"]+|\\\\\n|%s|%s|[\\\\\'"]){0,255})$' % (regexp_db_qstr, regexp_si_qstr)) +
		'|^(?P<option_space>\s+)(?P<option>-[a-zA-Z0-9]\\b|--[^ \t\n]+)(?P<option_desc>.*)$'
		'|^(?P<note>\(.*\))$'
		, re.M)
regexp_string = re.compile('(?:%s|%s)' % (regexp_db_qstr, regexp_si_qstr))
def execute(hdf, txt, env):
	# args will be null if the macro is called without parenthesis.
	css = ''
	if hdf:
		if not hdf.has_key("macro.ShellExample.outputcss"):
			hdf["macro.ShellExample.outputcss"] = True
			css = '''<style type="text/css">
.code-input          {color:blue}
.code-input          {color:blue}
.code-root           {color:red;}
.code-note           {color:#d80000;}
.code-path, .code-user {color:#449999; font-weight: bold}
</style>'''
	txt = txt and regex_crlf.sub("\n", escape(txt).replace('&#34;', '"')) or ''
	def stringcallback(match):
		return '<span class="code-string">' + match.group(0) + '</span>'

	def callback(match):
		m = match.group('cli')
		if m:
			path = match.group('path')
			if path:
				line = '<span class="code-path">' + path + '</span>'
			else:
				line = ''

			input = regexp_string.sub(stringcallback, match.group('input'))
			input = '<span class="code-input">' + input + '</span>'
			if m == '# ':
				line = line + '<span class="code-root">' + m + input + '</span>'
			else:
				line = line + '<span class="code-user">' + m + input + '</span>'
			return line
		m = match.group('option')
		if m:
			space = match.group('option_space')
			desc  = match.group('option_desc')
			return space + '<span class="code-func">' + m + '</span>' + desc
		m = match.group('note')
		if m:
			return '<span class="code-note">' + m + '</span>'
		return match.group(0)
	return css + '<div class="code"><pre>' + regexp.sub(callback, txt)+ '</pre></div>';
