indexing
	description: "Can format Eiffel for ASP.NET page into colored HTML."
	note:	"The page should user lower case for all tags and include: %
					%- 
... l_count
					loop
						if l_in_tag then
							if is_end_tag (l_source, i) then
								l_in_tag := false
								l_tag.append_character (l_source.item (i))
								internal_formatted_html.append (formatted_tag (l_tag))
								if l_tag.is_equal ("<script runat="server">") then
									l_index := l_source.substring_index ("</script>", i + 1)
									if l_index > 0 then
										internal_formatted_html.append (eiffel_format (l_source.substring (i + 1, l_index - 1)))
										i := l_index - 1
									end
								elseif l_tag.is_equal ("<title>") then
									l_index := l_source.substring_index ("</title>", i + 1)
									if l_index > 0 then
										internal_page_title := l_source.substring (i + 1, l_index - 1)
									end
								end
							else
								l_tag.append_character (l_source.item (i))
							end
						else
							l_in_tag := is_start_tag (l_source, i)
							if l_in_tag then
								create l_tag.make (50)
								l_tag.append ("<")
								internal_formatted_html.keep_head (internal_formatted_html.count - 3) -- Remove "<" from `internal_formatted_html'
							else
								internal_formatted_html.append_character (l_source.item (i))
							end
						end
						i := i + 1
					end
					internal_formatted_html.replace_substring_all ("%T", "   ")
					internal_formatted_html.replace_substring_all ("%R%N", "
")
					internal_formatted_html.replace_substring_all ("%N", "
")
					internal_page_description := subtext (l_source, "description: %"", "%"")
					if internal_page_title = Void then
						internal_page_title := ""
					end
					parse_successful := True
				end
			end
		ensure
			attached_formatted_html_iff_successful: parse_successful = (formatted_html /= Void)
			attached_page_title_iff_successful: parse_successful = (page_title /= Void)
			attached_page_description_iff_successful: parse_successful = (page_description /= Void)
		rescue
			l_retried := True
			retry
		end
feature -- Status Report
	parse_successful: BOOLEAN
			-- Was last call to `parse' successful?
feature -- Access
		
	formatted_html: STRING is
			-- HTML page representing source code
		require
			parsed: parse_successful
		do
			Result := internal_formatted_html
		end
	page_title: STRING is
			-- Last parsed page title
		require
			parsed: parse_successful
		do
			Result := internal_page_title
		end
	page_description: STRING is
			-- Last parsed page description
		require
			parsed: parse_successful
		do
			Result := internal_page_description
		end
feature {NONE} -- Implementation
	internal_formatted_html, internal_page_title, internal_page_description: STRING
			-- Parse results
	is_end_tag (a_source: STRING; a_index: INTEGER): BOOLEAN is
			-- Is character at index `a_index' in `a_source' closing html tag?
		require
			attached_source: a_source /= void
			valid_index: a_index > 0 and a_index <= a_source.count
		do
			if a_index > 3 then
				Result := a_source.item (a_index) = ';' and
							a_source.item (a_index - 1) = 't' and
							a_source.item (a_index - 2) = 'g' and
							a_source.item (a_index - 3) = '&'
			end
		end
	is_start_tag (a_source: STRING; a_index: INTEGER): BOOLEAN is
			-- Is character at index `a_index' in `a_source' opening html tag?
		require
			attached_source: a_source /= void
			valid_index: a_index > 0 and a_index <= a_source.count
		do
			if a_index > 3 then
				Result := a_source.item (a_index) = ';' and
							a_source.item (a_index - 1) = 't' and
							a_source.item (a_index - 2) = 'l' and
							a_source.item (a_index - 3) = '&'
			end
		end
	formatted_tag (a_tag: STRING): STRING is
			-- Use `Html_formats' to format tag.
			-- `a_tag' can be of the form '!doctype' or '/table' or 'br /' or 'a href=...'
		require
			attached_tag: a_tag /= void
			valid_tag: a_tag.substring (1, 4).is_equal ("<") and 
					a_tag.substring (a_tag.count - 3, a_tag.count).is_equal (">")
		local
			i, l_count, l_index: INTEGER
			c: CHARACTER
			l_tag: STRING
			l_in_tag: BOOLEAN
		do
			l_count := a_tag.count
			if a_tag.substring (1, 7).is_equal ("<!--") and
						a_tag.substring (l_count - 5, l_count).is_equal ("-->") then
					-- Special case for comments
				create Result.make (a_tag.count + 30)
				Result.append ("")
			else
				create Result.make (l_count + 30)
				if a_tag.item (5) = '/' then
					Result.append ("</")
					i := 6
				else
					Result.append ("<")
					i := 5
				end
				from
				until
					i > l_count - 4
				loop
					c := a_tag.item (i)
					if l_in_tag then
						if is_quote_start (a_tag, i) then
							l_index := a_tag.substring_index (""", i + 1)
							if l_index > 0 then
								Result.keep_head (Result.count - 1) -- Remove "&" from Result
								Result.append (""")
								Result.append (a_tag.substring (i + 1, l_index - 1))
								Result.append (""")
								i := l_index + 5
							end
							l_tag.wipe_out -- Remove "quot" from tag content
						elseif not c.is_alpha_numeric and c /= '!' and c /= '-' then
							l_in_tag := false
							Html_formats.search (l_tag)
							if Html_formats.found then
								Result.append (Html_formats.found_item)
							else
								Result.append (l_tag)
							end
							Result.append_character (c)
						else
							l_tag.append_character (c)
						end
					else
						l_in_tag := c.is_alpha_numeric or c = '!' or c = '-'
						if l_in_tag then
							create l_tag.make (50)
							l_tag.append_character (c)
						else
							Result.append_character (c)
						end
					end
					i := i + 1
				end
				if l_in_tag then
					Html_formats.search (l_tag)
					if Html_formats.found then
						Result.append (Html_formats.found_item)
					else
						Result.append (l_tag)
					end
				end
				Result.append (">")
			end
		end
	is_quote_start (a_tag: STRING; a_index: INTEGER): BOOLEAN is
			-- Does character at index `a_index' in `a_tag' correspond to start of HTML quote?
		require
			attached_tag: a_tag /= Void
			valid_index: a_index > 0 and a_index <= a_tag.count
		do
			if a_index > 5 then
				Result := a_tag.item (a_index) = ';' and
						a_tag.item (a_index - 1) = 't' and
						a_tag.item (a_index - 2) = 'o' and
						a_tag.item (a_index - 3) = 'u' and
						a_tag.item (a_index - 4) = 'q' and
						a_tag.item (a_index - 5) = '&' and
						a_tag.item (a_index - 6) /= '%''
			end
		end
	eiffel_format (a_source: STRING): STRING is
			-- HTML code with added css styles to HTML encoded Eiffel source `a_source'
		require
			attached_source: a_source /= void
		local
			l_in_word, l_found: BOOLEAN
			i, j, l_count, l_index: INTEGER
			c: CHARACTER
			l_word: STRING
		do
			l_count := a_source.count
			create Result.make (l_count * 2)
			create l_word.make (128)
			from
				i := 1
			until
				i > l_count
			loop
				c := a_source.item (i)
				if is_quote_start (a_source, i) then
					from
						l_index := i
						l_found := False
					until
						l_found or l_index = 0
					loop
						l_index := a_source.substring_index (""", l_index + 1)
						l_found := l_index > 0 and then a_source.item (l_index - 1) /= '%%'
					end
					
					if l_found then
						Result.keep_head (Result.count - 1) -- Remove "&" from Result
						create l_word.make (128) -- Reset content of `l_word'
						Result.append (""")
						Result.append (a_source.substring (i + 1, l_index - 1))
						Result.append (""")
						i := l_index + 5
					end
				elseif l_in_word then
					if not c.is_alpha_numeric and c /= '_' then
						l_in_word := False
						Eiffel_formats.search (l_word)
						if Eiffel_formats.found then
							Result.append (Eiffel_formats.found_item)
						elseif l_word.is_integer then
							Result.append ("")
							Result.append (l_word)
							Result.append ("")
						elseif l_word.as_upper.is_equal (l_word) then
							Result.append ("")
							Result.append (l_word)
							Result.append ("")
						else
							Result.append (l_word)
						end
						if c = '.' then
							Result.append ("")
							Result.append_character ('.')
							Result.append ("")
						else
							Result.append_character (c)
						end
					else
						l_word.append_character (c)
					end
				elseif c = '-' and a_source.item (i - 1) = '-' then
					j := a_source.index_of ('%N', i + 1)
					if j > 0 then
						Result.keep_head (Result.count - 1) -- Remove "-" from Result
						Result.append ("
")
						i := j
					else
						Result.append_character (c)
					end
				else
					l_in_word := c.is_alpha_numeric
					if l_in_word then
						create l_word.make (80)
						l_word.append_character (c)
					elseif c = '.' then
						Result.append ("")
						Result.append_character ('.')
						Result.append ("")
					else
						Result.append_character (c)
					end
				end
				i := i + 1
			end
		ensure
			attached_code: Result /= void
		end
	subtext (a_source, a_start_tag, a_end_tag: STRING): STRING is
			-- Text in `a_source' in between `a_start_tag' and `a_end_tag'
		require
			attached_source: a_source /= void
			attached_start_tag: a_start_tag /= void
			attached_end_tag: a_end_tag /= void
		local
			l_index, l_index_2: integer
		do
			l_index := a_source.substring_index (a_start_tag, 1)
			if l_index > 0 then
				l_index_2 := a_source.substring_index (a_end_tag, l_index + a_start_tag.count)
				if l_index_2 > 0 then
					Result := a_source.substring (l_index + a_start_tag.count, l_index_2 - 1)
				end
			end
			if Result = void then
				Result := ""
			end
		ensure
			attached_text: Result /= void
		end
	Eiffel_formats: HASH_TABLE [STRING, STRING] is
			-- Eiffel keywords and corresponding formatting
		once
			create Result.make (66)
			-- Keywords
			Result.put ("class", "class")
			Result.put ("deferred", "deferred")
			Result.put ("expanded", "expanded")
			Result.put ("feature", "feature")
			Result.put ("indexing", "indexing")
			Result.put ("inherit", "inherit")
			Result.put ("separate", "separate")
			Result.put ("agent", "agent")
			Result.put ("alias", "alias")
			Result.put ("all", "all")
			Result.put ("and", "and")
			Result.put ("as", "as")
			Result.put ("assertion", "assertion")
			Result.put ("create", "create")
			Result.put ("creation", "creation")
			Result.put ("debug", "debug")
			Result.put ("do", "do")
			Result.put ("exclude", "exclude")
			Result.put ("else", "else")
			Result.put ("elseif", "elseif")
			Result.put ("end", "end")
			Result.put ("export", "export")
			Result.put ("external", "external")
			Result.put ("from", "from")
			Result.put ("frozen", "frozen")
			Result.put ("if", "if")
			Result.put ("implies", "implies")
			Result.put ("include", "include")
			Result.put ("infix", "infix")
			Result.put ("inspect", "inspect")
			Result.put ("is", "is")
			Result.put ("like", "like")
			Result.put ("local", "local")
			Result.put ("loop", "loop")
			Result.put ("not", "not")
			Result.put ("obsolete", "obsolete")
			Result.put ("old", "old")
			Result.put ("once", "once")
			Result.put ("or", "or")
			Result.put ("override_cluster", "override_cluster")
			Result.put ("prefix", "prefix")
			Result.put ("redefine", "redefine")
			Result.put ("rename", "rename")
			Result.put ("rescue", "rescue")
			Result.put ("retry", "retry")
			Result.put ("select", "select")
			Result.put ("strip", "strip")
			Result.put ("then", "then")
			Result.put ("undefine", "undefine")
			Result.put ("unique", "unique")
			Result.put ("until", "until")
			Result.put ("visible", "visible")
			Result.put ("when", "when")
			Result.put ("xor", "xor")
			-- DBC
			Result.put ("check", "check")
			Result.put ("ensure", "ensure")
			Result.put ("invariant", "invariant")
			Result.put ("require", "require")
			Result.put ("variant", "variant")
			-- Reserved words
			Result.put ("Current", "Current")
			Result.put ("False", "False")
			Result.put ("Precursor", "Precursor")
			Result.put ("Result", "Result")
			Result.put ("True", "True")
			Result.put ("Void", "Void")
		end
	
	Html_formats: HASH_TABLE [STRING, STRING] is
			-- HTML keywords and corresponding formatting
		once
			create Result.make (224)
			-- HTML keywords
			Result.put ("!doctype", "!doctype")
			Result.put ("a", "a")
			Result.put ("abbr", "abbr")
			Result.put ("acronym", "acronym")
			Result.put ("address", "address")
			Result.put ("applet", "applet")
			Result.put ("area", "area")
			Result.put ("b", "b")
			Result.put ("base", "base")
			Result.put ("basefont", "basefont")
			Result.put ("bdo", "bdo")
			Result.put ("bgsound", "bgsound")
			Result.put ("big", "big")
			Result.put ("blink", "blink")
			Result.put ("blockquote", "blockquote")
			Result.put ("body", "body")
			Result.put ("br", "br")
			Result.put ("button", "button")
			Result.put ("caption", "caption")
			Result.put ("center", "center")
			Result.put ("cite", "cite")
			Result.put ("code", "code")
			Result.put ("col", "col")
			Result.put ("colgroup", "colgroup")
			Result.put ("dd", "dd")
			Result.put ("del", "del")
			Result.put ("dfn", "dfn")
			Result.put ("dir", "dir")
			Result.put ("div", "div")
			Result.put ("dl", "dl")
			Result.put ("dt", "dt")
			Result.put ("em", "em")
			Result.put ("embed", "embed")
			Result.put ("fieldset", "fieldset")
			Result.put ("font", "font")
			Result.put ("form", "form")
			Result.put ("frame", "frame")
			Result.put ("frameset", "frameset")
			Result.put ("h1", "h1")
			Result.put ("h2", "h2")
			Result.put ("h3", "h3")
			Result.put ("h4", "h4")
			Result.put ("h5", "h5")
			Result.put ("h6", "h6")
			Result.put ("head", "head")
			Result.put ("hr", "hr")
			Result.put ("html", "html")
			Result.put ("http-equiv", "http-equiv")
			Result.put ("i", "i")
			Result.put ("iframe", "iframe")
			Result.put ("ilayer", "ilayer")
			Result.put ("img", "img")
			Result.put ("input", "input")
			Result.put ("ins", "ins")
			Result.put ("isindex", "isindex")
			Result.put ("kbd", "kbd")
			Result.put ("keygen", "keygen")
			Result.put ("label", "label")
			Result.put ("layer", "layer")
			Result.put ("legend", "legend")
			Result.put ("li", "li")
			Result.put ("link", "link")
			Result.put ("listing", "listing")
			Result.put ("map", "map")
			Result.put ("menu", "menu")
			Result.put ("meta", "meta")
			Result.put ("multicol", "multicol")
			Result.put ("nobr", "nobr")
			Result.put ("noembed", "noembed")
			Result.put ("noframes", "noframes")
			Result.put ("nolayer", "nolayer")
			Result.put ("noscript", "noscript")
			Result.put ("object", "object")
			Result.put ("ol", "ol")
			Result.put ("optgroup", "optgroup")
			Result.put ("option", "option")
			Result.put ("p", "p")
			Result.put ("param", "param")
			Result.put ("plaintext", "plaintext")
			Result.put ("pre", "pre")
			Result.put ("q", "q")
			Result.put ("ruby", "ruby")
			Result.put ("s", "s")
			Result.put ("samp", "samp")
			Result.put ("script", "script")
			Result.put ("select", "select")
			Result.put ("server", "server")
			Result.put ("small", "small")
			Result.put ("sound", "sound")
			Result.put ("spacer", "spacer")
			Result.put ("span", "span")
			Result.put ("strike", "strike")
			Result.put ("strong", "strong")
			Result.put ("style", "style")
			Result.put ("sub", "sub")
			Result.put ("sup", "sup")
			Result.put ("tbody", "tbody")
			Result.put ("textarea", "textarea")
			Result.put ("title", "title")
			Result.put ("tt", "tt")
			Result.put ("u", "u")
			Result.put ("ul", "ul")
			Result.put ("var", "var")
			Result.put ("wbr", "wbr")
			Result.put ("xmp", "xmp")
			Result.put ("table", "table")
			Result.put ("td", "td")
			Result.put ("tfoot", "tfoot")
			Result.put ("th", "th")
			Result.put ("thead", "thead")
			Result.put ("tr", "tr")
			-- HTML Attributes
			Result.put ("accesskey", "accesskey")
			Result.put ("action", "action")
			Result.put ("align", "align")
			Result.put ("alink", "alink")
			Result.put ("alt", "alt")
			Result.put ("background", "background")
			Result.put ("balance", "balance")
			Result.put ("behavior", "behavior")
			Result.put ("bgcolor", "bgcolor")
			Result.put ("bgproperties", "bgproperties")
			Result.put ("border", "border")
			Result.put ("bordercolor", "bordercolor")
			Result.put ("bordercolordark", "bordercolordark")
			Result.put ("bordercolorlight", "bordercolorlight")
			Result.put ("bottommargin", "bottommargin")
			Result.put ("cellpadding", "cellpadding")
			Result.put ("cellspacing", "cellspacing")
			Result.put ("checked", "checked")
			Result.put ("class", "class")
			Result.put ("classid", "classid")
			Result.put ("clear", "clear")
			Result.put ("code", "code")
			Result.put ("codebase", "codebase")
			Result.put ("codetype", "codetype")
			Result.put ("color", "color")
			Result.put ("cols", "cols")
			Result.put ("colspan", "colspan")
			Result.put ("compact", "compact")
			Result.put ("content", "content")
			Result.put ("controls", "controls")
			Result.put ("coords", "coords")
			Result.put ("datafld", "datafld")
			Result.put ("dataformatas", "dataformatas")
			Result.put ("datasrc", "datasrc")
			Result.put ("direction", "direction")
			Result.put ("disabled", "disabled")
			Result.put ("dynsrc", "dynsrc")
			Result.put ("enctype", "enctype")
			Result.put ("event", "event")
			Result.put ("face", "face")
			Result.put ("for", "for")
			Result.put ("frame", "frame")
			Result.put ("frameborder", "frameborder")
			Result.put ("framespacing", "framespacing")
			Result.put ("height", "height")
			Result.put ("hidden", "hidden")
			Result.put ("href", "href")
			Result.put ("hspace", "hspace")
			Result.put ("ismap", "ismap")
			Result.put ("lang", "lang")
			Result.put ("language", "language")
			Result.put ("leftmargin", "leftmargin")
			Result.put ("link", "link")
			Result.put ("loop", "loop")
			Result.put ("lowsrc", "lowsrc")
			Result.put ("marginheight", "marginheight")
			Result.put ("marginwidth", "marginwidth")
			Result.put ("maxlength", "maxlength")
			Result.put ("mayscript", "mayscript")
			Result.put ("method", "method")
			Result.put ("methods", "methods")
			Result.put ("multiple", "multiple")
			Result.put ("name", "name")
			Result.put ("nohref", "nohref")
			Result.put ("noresize", "noresize")
			Result.put ("noshade", "noshade")
			Result.put ("nowrap", "nowrap")
			Result.put ("palette", "palette")
			Result.put ("pluginspage", "pluginspage")
			Result.put ("public", "public")
			Result.put ("rb", "rb")
			Result.put ("rbc", "rbc")
			Result.put ("readonly", "readonly")
			Result.put ("rel", "rel")
			Result.put ("rev", "rev")
			Result.put ("rightmargin", "rightmargin")
			Result.put ("rows", "rows")
			Result.put ("rowspan", "rowspan")
			Result.put ("rp", "rp")
			Result.put ("rt", "rt")
			Result.put ("rtc", "rtc")
			Result.put ("rules", "rules")
			Result.put ("scroll", "scroll")
			Result.put ("scrollamount", "scrollamount")
			Result.put ("scrolldelay", "scrolldelay")
			Result.put ("scrolling", "scrolling")
			Result.put ("selected", "selected")
			Result.put ("shape", "shape")
			Result.put ("size", "size")
			Result.put ("span", "span")
			Result.put ("src", "src")
			Result.put ("start", "start")
			Result.put ("style", "style")
			Result.put ("tabindex", "tabindex")
			Result.put ("target", "target")
			Result.put ("text", "text")
			Result.put ("title", "title")
			Result.put ("topmargin", "topmargin")
			Result.put ("truespeed", "truespeed")
			Result.put ("type", "type")
			Result.put ("url", "url")
			Result.put ("urn", "urn")
			Result.put ("usemap", "usemap")
			Result.put ("valign", "valign")
			Result.put ("value", "value")
			Result.put ("vlink", "vlink")
			Result.put ("volume", "volume")
			Result.put ("vrml", "vrml")
			Result.put ("vspace", "vspace")
			Result.put ("width", "width")
			Result.put ("wrap", "wrap")
			-- ASP.NET
			Result.put ("page", "page")
			Result.put ("asp", "asp")
			Result.put ("Label", "Label")
			Result.put ("Textbox", "Textbox")
			Result.put ("RequiredFieldValidator", "RequiredFieldValidator")
			Result.put ("CustomValidator", "CustomValidator")
			Result.put ("Button", "Button")
			Result.put ("DataList", "DataList")
			Result.put ("Hyperlink", "Hyperlink")
			-- ASP.NET Controls properties
			Result.put ("runat", "runat")
			Result.put ("id", "id")
			Result.put ("Text", "Text")
			Result.put ("OnServerValidate", "OnServerValidate")
			Result.put ("OnClick", "OnClick")
			Result.put ("Display", "Display")
			Result.put ("ControlToValidate", "ControlToValidate")
			Result.put ("DataList", "DataList")
			Result.put ("BorderColor", "BorderColor")
			Result.put ("BorderWidth", "BorderWidth")
			Result.put ("CellPadding", "CellPadding")
			Result.put ("CellSpacing", "CellSpacing")
			Result.put ("GridLines", "GridLines")
			Result.put ("ItemTemplate", "ItemTemplate")
			Result.put ("CssClass", "CssClass")
		end
end -- class CODE_FORMATTER
--+--------------------------------------------------------------------
--| Eiffel for ASP.NET 5.6
--| Copyright (c) 2005-2006 Eiffel Software
--|
--| Eiffel Software
--| 356 Storke Road, Goleta, CA 93117 USA
--| http://www.eiffel.com
--+--------------------------------------------------------------------