Click here to Skip to main content
Click here to Skip to main content
Add your own
alternative version

WPF HTML Supported TextBlock

, 7 Feb 2009 LGPL3
This article describes HtmlTextBlock which is a WPF TextBlock that can parse a limited set of HTML tags and display them.
/*
 * Created by SharpDevelop.
 * User: Joseph Leung
 * Date: 8/9/2006
 * Time: 11:14 PM
 * 
 * To change this template use Tools | Options | Coding | Edit Standard Headers.
 */

using System;
using System.Collections;
using System.Collections.Specialized;
using QuickZip.MiniHtml2;

namespace QuickZip.MiniCss
{	
	/// <summary>
	/// Convert Header string to useable type.
	/// </summary>
	public class CssHeaderStyleType
	{
		public static string UnspecifiedTagName = "n0ne";
		public enum ElementType {Unknown, FirstChar, FirstLine, FirstLetter,
						Link, Visited, Focused, Hover, Active};
		public ElementType elements;
		public string tagName;
		public string tagClass;
		public string tagID; 
		public bool familyTag;
		public bool noOtherClassID;

		public static ElementType ElementsToCssElementType(string input)
		{
			switch (input)
			{
				case ("first-char"):
					return ElementType.FirstChar;
				case ("first-line"):
					return ElementType.FirstLine;
				case ("first-letter"):
					return ElementType.FirstLetter;
				case ("link"):
					return ElementType.Link;
				case ("visited"):
					return ElementType.Visited;
				case ("focused"):
					return ElementType.Focused;
				case ("hover"):
					return ElementType.Hover;
				default:
					return ElementType.Active;
			}
		}
		public void PrintItems()
		{
			string fmt = "Name:{0}, ID:{1}, Cls:{2}, EleIdx:{3}, Flags:{4}{5}";
			string f = "_"; if (familyTag) f = "F"; 
			string n = "_"; if (noOtherClassID) n = "N"; 
			Console.WriteLine(String.Format(fmt, tagName, tagID, tagClass, 
			                              (Int32)elements, f, n));
		}
		
		public string Css()
		{
			string idStr = "";
			string classStr = "";
			if (tagID != "") idStr = "#" + tagID;
			if (tagClass != "") classStr = "." + tagClass;
			return tagName + idStr + classStr + " ";				
		}
		
		public CssHeaderStyleType(string header)
		{
			elements = ElementType.Unknown;
			familyTag = false;
			noOtherClassID = false;
			tagID = "";
			tagClass = "";
			
			string k = header;
			
			char lastChar = k[k.Length-1];
			switch (lastChar)
			{
				case '+':
					familyTag = true;
					k = k.Substring(0, k.Length - 1);
					break;
				case '>':
					noOtherClassID = true;
					k = k.Substring(0, k.Length - 1);
					break;
			}
			
			if (k.IndexOf('#') > -1)
				tagID = Utils.ExtractAfter(ref k, '#');
			if (k.IndexOf('.') > -1)
				tagClass = Utils.ExtractAfter(ref k, '.');
			if (k.IndexOf(':') > -1)
				elements = CssHeaderStyleType.ElementsToCssElementType(
				           		Utils.ExtractAfter(ref k, ':'));
			tagName = k;
			if (tagName.Trim() == "")
				tagName = UnspecifiedTagName;

		}
	}
	
	/// <summary>
	/// Store one record of a full css style (header and styles)
	/// </summary>
	public class CssStyleType
	{
		public string tagName;
		public string styleTagName;
		public ArrayList parentTagName;
		public string styleClass;
		public string styleID;
		public PropertyList styles;
		
		public CssStyleType()
		{
			parentTagName = new ArrayList();
			styles = new PropertyList();
		}
		~CssStyleType()
		{			
			styles = null;
			parentTagName = null;
		}
		public string printParentTagName()
		{
			string retVal = "";
			foreach (object o in parentTagName)
			{
				retVal += ',' + (string)o;
			}
			return retVal.Trim(',');
		}
	}
	
	public class CssStyleGroupType
	{
		public string styleTagName;
		public ArrayList parentTagName;
		
		public CssStyleGroupType()
		{
			parentTagName = new ArrayList();
		}
		~CssStyleGroupType()
		{
			parentTagName = null;
		}
	}
	
	/// <summary>
	/// A List of CssStyleType
	/// </summary>
	public class CssStyleList : CollectionBase
	{
		private CssStyleType getCssStyle(Int32 index)
		{
			return (CssStyleType)List[index];
		}
		
		private void setCssStyle(Int32 index, CssStyleType value)
		{
			List[index] = value;
		}
		
		private void verifyType(object value)
		{
			if (value == null)
				throw new ArgumentException("Nil exception");
			if (!(value is CssStyleType))
				throw new ArgumentException("Invalid Type - " + value.ToString());
		}
		
		protected override void OnInsert(int index, object value)
		{
			verifyType(value);
			base.OnInsert(index, value);
		}
		
		protected override void OnSet(int index, object oldValue, object newValue)
		{
			verifyType(newValue);
			base.OnSet(index, oldValue, newValue);
		}
		
		protected override void OnValidate(object value)
		{
			verifyType(value);
			base.OnValidate(value);
		}
		
		public CssStyleList() : base()
		{
			
		}
		
		~CssStyleList()
		{
			List.Clear();
		}
		
		public Int32 Add(CssStyleType value)
		{
			return List.Add(value);
		}
		
		public void Insert(Int32 index, CssStyleType value)
		{
			List.Insert(index, value);
		}
		
		public void Remove(CssStyleType value)
		{
			List.Remove(value);
		}
		
		public bool Contains(CssStyleType value)
		{
			return List.Contains(value);
		}
		
		public void PrintItems()
		{
			for (Int32 i = 0; i < Count; i++)
			{
				CssStyleType c = this[i];
				CssHeaderStyleType style = new CssHeaderStyleType(c.styleTagName);
				style.PrintItems();
				
				for (Int32 j = 0; j < c.styles.Count; j++)
				{
					string output = String.Format("[key: {0} = {1}]", 
					                              c.styles[j].key, c.styles[j].value);
					Console.WriteLine(output);					
				}
				Console.WriteLine("");
			}
		}
		
		public string Css()
		{
			string retVal = "";
			for (Int32 i = 0; i < Count; i++)
			{
				CssStyleType c = this[i];
				CssHeaderStyleType style = new CssHeaderStyleType(c.styleTagName);
				retVal += style.Css() + "{ ";
				
				for (Int32 j = 0; j < c.styles.Count; j++)
					retVal += c.styles[j].key + ":" + c.styles[j].value + ";";													
				
				retVal += " }" + Defines.lineBreak;
			}
			return retVal;
		}
		
		public CssStyleType this[Int32 index]
		{
			get
			{
				return getCssStyle(index);
			}
			set
			{
				setCssStyle(index, value);
			}
		}
	}
	
	/// <summary>
	/// A List of CssStyleType for specified tag
	/// </summary>
	public class TagCssStyleType
	{
		public string tagName;
		public CssStyleList cssStyles;
		public TagCssStyleType(string aTagName) : base()
		{
			tagName = aTagName;
			cssStyles = new CssStyleList();
		}
		~TagCssStyleType() 
		{
			cssStyles = null;
		}
		public void AddCssStyle(CssStyleType aStyle)
		{
			cssStyles.Add(aStyle);
		}
		
	}
	
	/// <summary>
	/// Container of all TagCssStyleType (All cssStyles for all tags)
	/// </summary>
	public class TagCssStyleDictionary : ListDictionary
	{
		private TagCssStyleType getCssTagStyle(string key)
		{
			if (Contains(key))
			{
				foreach (DictionaryEntry de in this)
					if ((string)de.Key == key)
					return (TagCssStyleType)(de.Value);
			}
			
			return new TagCssStyleType(key);
		}
		private TagCssStyleType getCssTagStyle(Int32 id)
		{
			IDictionaryEnumerator em = this.GetEnumerator();
			if (Count >= id)
			{
				for (Int32 i = 0; i <= id; i++)
					em.MoveNext();
				return (TagCssStyleType)(em.Value);
			}
			return new TagCssStyleType(id.ToString());
		}
		private void setCssTagStyle(string key, TagCssStyleType value)
		{
			if (Contains(key))
			{
				foreach (DictionaryEntry de in this)
					if ((string)de.Key == key)
					{
						DictionaryEntry te = de;
						te.Value = value;
						return;
					}				
			}
			else
				Add(key, value);
		}		
		private void verifyType(object value)
		{
			if (!(value is TagCssStyleType))
				throw new ArgumentException("Invalid Type");
		}
		
		public TagCssStyleDictionary() : base()
		{
			
		}
		
		~TagCssStyleDictionary()
		{
			
		}
		
		public void PrintItems()
		{
			IDictionaryEnumerator em = this.GetEnumerator();						
			while (em.MoveNext())			
				((TagCssStyleType)(em.Value)).cssStyles.PrintItems();			
		}
		
		public string Css()
		{
			string retVal = "";
			IDictionaryEnumerator em = this.GetEnumerator();						
			while (em.MoveNext())			
				retVal += ((TagCssStyleType)(em.Value)).cssStyles.Css();
			return retVal;
		}
		
		public void AddCssStyle(string input)
		{
			ArrayList css = Utils.DecodeCssStyle(input);
			for (Int32 i = 0; i < css.Count; i++)
			{
				CssStyleType cssStyle = (CssStyleType)(css[i]);								
				if (cssStyle.styleTagName != "")
				{
					if (!(Contains(cssStyle.tagName)))
						Add(cssStyle.tagName, new TagCssStyleType(cssStyle.tagName));											
					this[cssStyle.tagName].AddCssStyle(cssStyle);						
				}
			}			
		}
		
		public TagCssStyleType this[string input]
		{
			get
			{
				return getCssTagStyle(input);
			}
			set
			{
				setCssTagStyle(input, value);
			}			
		}
		
		public TagCssStyleType this[Int32 id]
		{
			get
			{
				return getCssTagStyle(id);
			}
		}
		
		public CssStyleList ListAllCssStyle(string tagName)
		{
			CssStyleList retVal = new CssStyleList();
			
			for (Int32 i = 0; i < this[tagName].cssStyles.Count; i++)
				retVal.Add(this[tagName].cssStyles[i]);
			for (Int32 i = 0; i < this[CssHeaderStyleType.UnspecifiedTagName].cssStyles.Count; i++)
				retVal.Add(this[CssHeaderStyleType.UnspecifiedTagName].cssStyles[i]);
			
			return retVal;
		}
		
	}

	
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The GNU Lesser General Public License (LGPLv3)

Share

About the Author


| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.141223.1 | Last Updated 7 Feb 2009
Article Copyright 2009 by Leung Yat Chun
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid