public void IsEmptyWhenNew()
        {
            this.stack = new Stack();

            bool isEmpty = this.stack.IsEmpty;

            Assert.IsTrue(isEmpty);
        }
Example #2
0
		internal void SetHtml(FrameworkElement rootElement, string htmlText, Control optionalFontTemplate)
		{
			try
			{
				// This is the main entry point, initialize everything
				_RootElement = rootElement;
				if (!(_RootElement is Panel || _RootElement is RichTextBox))
					return;
				if (_RootElement is Panel)
				{
					_CurrentRichTextBox = new RichTextBlock();
					(_RootElement as Panel).Children.Clear();
					(_RootElement as Panel).Children.Add(_CurrentRichTextBox);
				}
				else
				if (_RootElement is RichTextBox)
				{
					_CurrentRichTextBox = _RootElement as RichTextBox;
				}
				_CurrentParagraph = new Paragraph();
				_CurrentRichTextBox.Blocks.Add(_CurrentParagraph);

				// Setup the initial document state
				DocumentState documentState = new DocumentState();
				if (optionalFontTemplate == null)
					optionalFontTemplate = _RootElement as Control;
				if (optionalFontTemplate != null)
				{
					documentState.Brush = optionalFontTemplate.Foreground;
					documentState.Face = optionalFontTemplate.FontFamily.Source;
					documentState.Size = optionalFontTemplate.FontSize;
					documentState.Italic = (optionalFontTemplate.FontStyle == FontStyles.Italic);
					documentState.Bold = (optionalFontTemplate.FontWeight != FontWeights.Normal);
					documentState.Underline = false;
				}
				else
				{
					Run defaultRun = new Run();
					documentState.Brush = defaultRun.Foreground;
					documentState.Face = defaultRun.FontFamily.Source;
					documentState.Size = defaultRun.FontSize;
					documentState.Italic = (defaultRun.FontStyle == FontStyles.Italic);
					documentState.Bold = (defaultRun.FontWeight != FontWeights.Normal);
					documentState.Underline = (defaultRun.TextDecorations == TextDecorations.Underline);
				}

				_DocumentStates = new Stack<DocumentState>();
				_DocumentStates.Push(documentState);

				_PriorLineBreaks = 2; // As if we are following a paragraph

				bool hasMarkup = (htmlText != null && htmlText.IndexOf("<") >= 0 && htmlText.IndexOf(">") > 0);
				if (!hasMarkup) // translate ampersands & and the like
					htmlText = HttpUtility.HtmlEncode(htmlText);
				bool hasXmlDirective = (hasMarkup && htmlText.IndexOf("<?xml") >= 0);
				if (!hasXmlDirective) // add an outer <span> to ensure valid XML regardless of the text markup
					htmlText = string.Concat("<span>", htmlText, "</span>");
				bool hasInvalidEntity = (htmlText.IndexOf("&nbsp;") >= 0);
				if (hasInvalidEntity)
					htmlText = htmlText.Replace("&nbsp;", "&#160;");
				hasInvalidEntity = (htmlText.IndexOf("&copy;") >= 0);
				if (hasInvalidEntity)
					htmlText = htmlText.Replace("&copy;", "&#169;");

				// Read the XML DOM input
				StringReader stringReader = new StringReader(htmlText);
				XmlReaderSettings settings = new XmlReaderSettings();
				settings.DtdProcessing = DtdProcessing.Ignore;
				settings.IgnoreWhitespace = false;
				settings.IgnoreProcessingInstructions = true;
				settings.IgnoreComments = true;
				//settings.CheckCharacters = false;
				//settings.ConformanceLevel = ConformanceLevel.Auto;
				XmlReader xmlReader = XmlReader.Create(stringReader, settings);
				while (xmlReader.Read())
				{
					string nameLower = xmlReader.Name.ToLower();
					if (xmlReader.NodeType == XmlNodeType.Element)
					{
						// Process the element start
						bool bEmpty = xmlReader.IsEmptyElement;
						switch (nameLower)
						{
							// Process the following elements:
							// "style"
							// "a" "img" "font"
							// "b" "strong"
							// "h1" "h2" "h3" "h4" "h5" "h6"
							// "i" "em" "cite"
							// "u" "br" "pre" "code" "tt"
							// "p" "form"
							// "ol" "ul" "blockquote" "dir" "menu"
							// "li" "div" "center" "span"
							case "head":
							case "object":
							case "meta":
							case "title":
							case "script":
							case "noscript":
							{
								_IgnoreText = true;
								break;
							}

							case "style":
							{
								_InternalStyles = string.Empty;
								break;
							}

							case "link":
							{
								string rel = null;
								string href = null;
								if (xmlReader.MoveToFirstAttribute())
								do
								{
									if (xmlReader.Name.ToLower() == "rel")
										rel = xmlReader.Value;
									else
									if (xmlReader.Name.ToLower() == "href")
										href = xmlReader.Value;
								}
								while (xmlReader.MoveToNextAttribute());

								if (rel == "stylesheet" && href != null)
								{
									if (_DocumentUri != null)
										href = _DocumentUri.Site().Append(href).ToString();
									//j	CssParser.DownloadStyles(UriHelper.MakeAbsolute(_DocumentUri.Site(), href), ref _GlobalStyles);
								}
								break;
							}

							case "a":
							case "area":
							{
								if (bEmpty)
									break;

								DocumentState state = _DocumentStates.Peek();
								ProcessCommonStyles(ref state, xmlReader, nameLower);
								string href = null;
								if (xmlReader.MoveToFirstAttribute())
								do
								{
									if (xmlReader.Name.ToLower() == "href")
										href = xmlReader.Value;
								}
								while (xmlReader.MoveToNextAttribute());

								if (href != null)
								{
									if (_DocumentUri != null && !href.StartsWith("#"))
										href = _DocumentUri.Site().Append(href).ToString();
									state.Href = href;
								}

								_DocumentStates.Push(state);
								break;
							}

							case "base":
							{
								string href = null;
								if (xmlReader.MoveToFirstAttribute())
								do
								{
									if (xmlReader.Name.ToLower() == "href")
										href = xmlReader.Value;
								}
								while (xmlReader.MoveToNextAttribute());

								if (href != null)
									_DocumentUri = new Uri(href, UriKind.Absolute);
								break;
							}

							case "img":
							{
								string source = null;
								DocumentState state = _DocumentStates.Peek();
								if (xmlReader.MoveToFirstAttribute())
								do
								{
									if (xmlReader.Name.ToLower() == "src")
										source = xmlReader.Value;
								}
								while (xmlReader.MoveToNextAttribute());

								if (source != null)
								{
									if (_DocumentUri != null)
										source = _DocumentUri.Site().Append(source).ToString();
									AddImage(source);
								}
								break;
							}

							case "font":
							{
								if (bEmpty)
									break;

								DocumentState state = _DocumentStates.Peek();
								ProcessCommonStyles(ref state, xmlReader, nameLower);
								if (xmlReader.MoveToFirstAttribute())
								do
								{
									if (xmlReader.Name.ToLower() == "face")
										state.Face = xmlReader.Value;
									else
									if (xmlReader.Name.ToLower() == "size")
										state.Size = CssParser.ParseFontSize(xmlReader.Value, state.Size);
									else
									if (xmlReader.Name.ToLower() == "color")
										state.Brush = xmlReader.Value.ToColor().ToBrush();
								}
								while (xmlReader.MoveToNextAttribute());
								_DocumentStates.Push(state);
								break;
							}

							case "big":
							case "small":
							{
								if (bEmpty)
									break;

								DocumentState state = _DocumentStates.Peek();
								ProcessCommonStyles(ref state, xmlReader, nameLower);
								double percent = (nameLower == "big" ? 1.2 : .8);
								state.Size *= percent;
								_DocumentStates.Push(state);
								break;
							}
							
							case "b":
							case "strong":
							{
								if (bEmpty)
									break;

								DocumentState state = _DocumentStates.Peek();
								ProcessCommonStyles(ref state, xmlReader, nameLower);
								state.Bold = true;
								_DocumentStates.Push(state);
								break;
							}

							case "h1":
							case "h2":
							case "h3":
							case "h4":
							case "h5":
							case "h6":
							{
								MoveToBeginLine(true);
								if (bEmpty)
									break;

								DocumentState state = _DocumentStates.Peek();
								// Special h? font size handling
								if (!ProcessCommonStyles(ref state, xmlReader, nameLower))
									state.Size = CssParser.ParseFontSize(nameLower, state.Size);
								state.Bold = true;

								_DocumentStates.Push(state);
								break;
							}

							case "i":
							case "em":
							case "cite":
							case "address":
							case "dfn": // Definition term
							case "var": // Variable
							{
								if (bEmpty)
									break;

								DocumentState state = _DocumentStates.Peek();
								ProcessCommonStyles(ref state, xmlReader, nameLower);
								state.Italic = true;
								_DocumentStates.Push(state);
								break;
							}

							case "u":
							case "ins":
							{
								if (bEmpty)
									break;

								DocumentState state = _DocumentStates.Peek();
								ProcessCommonStyles(ref state, xmlReader, nameLower);
								state.Underline = true;
								_DocumentStates.Push(state);
								break;
							}

							case "s":
							case "strike":
							case "del":
							{
								if (bEmpty)
									break;

								DocumentState state = _DocumentStates.Peek();
								ProcessCommonStyles(ref state, xmlReader, nameLower);
								//state.StrikeThrough = true;
								_DocumentStates.Push(state);
								break;
							}

							case "br":
							{
								AddLineBreak();
								break;
							}

							case "pre":
							case "code":
							case "samp": // Sample computer code
							case "kbd":
							case "tt":
							{
								if (nameLower == "pre")
									MoveToBeginLine(true);
								if (bEmpty)
									break;

								DocumentState state = _DocumentStates.Peek();
								ProcessCommonStyles(ref state, xmlReader, nameLower);
								state.Face = "Courier New";
								_DocumentStates.Push(state);
								break;
							}

							case "ol":
							case "ul":
							case "dir": // Same as "ul"
							case "menu": // Same as "ul"
							{
								DocumentState state = _DocumentStates.Peek();
								bool newParagraph = (bEmpty || state.BulletType == '\0');
								MoveToBeginLine(newParagraph);
								if (bEmpty)
									break;

								ProcessCommonStyles(ref state, xmlReader, nameLower);
								state.BulletType = (nameLower == "ol" ? 'o' : 'u');
								state.ListItemNumber = 0;
								state.Indent += 8;
								_DocumentStates.Push(state);
								break;
							}

							case "li":
							{
								MoveToBeginLine(false);

								// Bump the list item number
								DocumentState state = _DocumentStates.Pop();
								state.ListItemNumber++;
								_DocumentStates.Push(state);

								//DocumentState state = _DocumentStates.Peek();
								ProcessCommonStyles(ref state, xmlReader, nameLower);
								_DocumentStates.Push(state);

								AddIndent();
								AddListItem();
								break;
							}

							case "blockquote":
							{
								MoveToBeginLine(true);
								if (bEmpty)
									break;

								DocumentState state = _DocumentStates.Peek();
								ProcessCommonStyles(ref state, xmlReader, nameLower);
								state.Indent += 8;
								_DocumentStates.Push(state);
								break;
							}

							case "div":
							case "p":
							case "body":
							case "form":
							case "center":
							case "textarea":
							{
								MoveToBeginLine(true);
								if (bEmpty)
									break;

								DocumentState state = _DocumentStates.Peek();
								ProcessCommonStyles(ref state, xmlReader, nameLower);
								_DocumentStates.Push(state);
								break;
							}

							case "table":
							case "caption":
							case "tr":
							case "td":
							{
								if (nameLower != "td")
									MoveToBeginLine(false);
								if (bEmpty)
									break;

								DocumentState state = _DocumentStates.Peek();
								ProcessCommonStyles(ref state, xmlReader, nameLower);
								_DocumentStates.Push(state);
								break;
							}

							case "sup":
							case "sub":
							{
								if (bEmpty)
									break;

								DocumentState state = _DocumentStates.Peek();
								ProcessCommonStyles(ref state, xmlReader, nameLower);
								_DocumentStates.Push(state);
								break;
							}

							case "dl":
							case "dt":
							case "dd":
							{
								bool newParagraph = (nameLower == "dl");
								MoveToBeginLine(newParagraph);
								if (bEmpty)
									break;

								DocumentState state = _DocumentStates.Peek();
								if (nameLower == "dd")
									state.Indent += 8;
								ProcessCommonStyles(ref state, xmlReader, nameLower);
								_DocumentStates.Push(state);
								break;
							}

							case "span":
							case "label":
							case "q":
							case "abbr":
							case "acronym":
							{
								if (bEmpty)
									break;

								DocumentState state = _DocumentStates.Peek();
								ProcessCommonStyles(ref state, xmlReader, nameLower);
								_DocumentStates.Push(state);
								break;
							}

							case "legend":
							{
								MoveToBeginLine(false);
								if (bEmpty)
									break;

								DocumentState state = _DocumentStates.Peek();
								ProcessCommonStyles(ref state, xmlReader, nameLower);
								_DocumentStates.Push(state);
								break;
							}
						}
					}
					else
					if (xmlReader.NodeType == XmlNodeType.EndElement)
					{
						// Process the element end
						switch (nameLower)
						{
							case "head":
							case "object":
							case "meta":
							case "title":
							case "script":
							case "noscript":
							{
								_IgnoreText = false;
								break;
							}

							case "style":
							{
								_GlobalSelectors = CssSelectors.Create(_InternalStyles);
								_InternalStyles = null;
								break;
							}

							case "link":
							{
								_IgnoreText = false;
								break;
							}

							case "a":
							case "area":
							{
								_DocumentStates.Pop();
								break;
							}

							case "base":
							{
								break;
							}

							case "img":
							{
								break;
							}

							case "font":
							{
								_DocumentStates.Pop();
								break;
							}

							case "big":
							case "small":
							{
								_DocumentStates.Pop();
								break;
							}

							case "b":
							case "strong":
							{
								_DocumentStates.Pop();
								break;
							}

							case "h1":
							case "h2":
							case "h3":
							case "h4":
							case "h5":
							case "h6":
							{
								MoveToBeginLine(true);
								_DocumentStates.Pop();
								break;
							}

							case "i":
							case "em":
							case "cite":
							case "address":
							case "dfn": // Definition term
							case "var": // Variable
							{
								_DocumentStates.Pop();
								break;
							}

							case "u":
							case "ins":
							{
								_DocumentStates.Pop();
								break;
							}

							case "s":
							case "strike":
							case "del":
							{
								_DocumentStates.Pop();
								break;
							}

							case "br":
							{
								break;
							}

							case "pre":
							case "code":
							case "samp": // Sample computer code
							case "kbd":
							case "tt":
							{
								if (nameLower == "pre")
									MoveToBeginLine(true);
								_DocumentStates.Pop();
								break;
							}

							case "ol":
							case "ul":
							case "dir":
							case "menu":
							{
								MoveToBeginLine(true);
								_DocumentStates.Pop();
								break;
							}

							case "li":
							{
								MoveToBeginLine(false);
								_DocumentStates.Pop();
								break;
							}

							case "blockquote":
							{
								MoveToBeginLine(true);
								_DocumentStates.Pop();
								break;
							}

							case "div":
							case "p":
							case "body":
							case "form":
							case "center":
							case "textarea":
							{
								MoveToBeginLine(false);
								_DocumentStates.Pop();
								break;
							}

							case "table":
							case "caption":
							case "tr":
							case "td":
							{
								if (nameLower != "td")
									MoveToBeginLine(false);
								_DocumentStates.Pop();
								break;
							}

							case "sup":
							case "sub":
							{
								_DocumentStates.Pop();
								break;
							}

							case "dl":
							case "dt":
							case "dd":
							{
								bool newParagraph = (nameLower == "dl");
								MoveToBeginLine(newParagraph);
								_DocumentStates.Pop();
								break;
							}

							case "span":
							case "label":
							case "q":
							case "abbr":
							case "acronym":
							{
								_DocumentStates.Pop();
								break;
							}

							case "legend":
							{
								MoveToBeginLine(false);
								_DocumentStates.Pop();
								break;
							}
						}
					}
					else
					if (xmlReader.NodeType == XmlNodeType.Text)
					{
						// Process the element text
						string text = "";
						try { text = xmlReader.Value; }
						catch (Exception ex)
						{
							text = ex.Message;
						}

						if (_InternalStyles != null)
							_InternalStyles += text;
						else
						if (!_IgnoreText)
						{
							// Remove redundant whitespace ala HTML
							StringBuilder builder = new StringBuilder(text.Length);
							char cLast = (_PriorLineBreaks > 0 ? ' ' : '\0');
							foreach (char ch in text)
							{
								char c = ch;
								if (c == '\t' || c == '\n') c = ' ';
								bool bSkip = (cLast == ' ' && c == ' ');
								cLast = c;
								if (!bSkip)
									builder.Append(c);
							}

							// Output the text
							string textRun = builder.ToString();
							AddText(textRun);
						}
					}
					else
					if (xmlReader.NodeType == XmlNodeType.Whitespace)
					{
						// Process the element whitespace
						if (_InternalStyles != null)
							_InternalStyles += " ";
						else
						if (!_IgnoreText)
						{
							// Remove redundant whitespace ala HTML
							bool bSkip = (_PriorLineBreaks > 0);
							if (!bSkip)
								AddText(" ");
						}
					}
				}

				FlushAll();
			}
			catch (Exception ex)
			{
				//ex.DebugOutput();
				ex.Alert();

				// Invalid XHTML; Clear any existing collection of Inlines
				if (_RootElement is RichTextBox)
				{
					(_RootElement as RichTextBox).Blocks.Clear();
					Paragraph paragraph = new Paragraph();
					paragraph.Inlines.Add(new Run() { Text = htmlText });
					(_RootElement as RichTextBox).Blocks.Add(paragraph);
				}
			}
			finally
			{
				_DocumentStates.Clear();
				_DocumentStates = null;

				if (_GlobalSelectors != null)
				{
					_GlobalSelectors.Dispose();
					_GlobalSelectors = null;
				}

				_RootElement = null;
				_CurrentRichTextBox = null;
				_CurrentParagraph = null;
			}
		}
Example #3
0
		public static void SetHtml(this TextBlock textBlock, string text)
		{
			// Constants
			try
			{
				FontProperties item = new FontProperties();
				item.face = textBlock.FontFamily.Source;
				item.size = textBlock.FontSize;
				item.brush = textBlock.Foreground;
				item.bold = false;
				item.italic = false;
				item.underline = false;
				item.listitem = false;
				item.listtype = 0;
				item.listitems = 0;
				item.indent = 0;
				item.link = null;
				g_sFonts = new Stack<FontProperties>();
				g_sFonts.Push(item);
				g_iPrevLineBreaks = 2;

				if (textBlock.Inlines == null)
					textBlock.Text = ""; // TextBlock Bug: work around the null inlines

				// Clear the collection of Inlines
				textBlock.Inlines.Clear();

				// Wrap the input in a <DIV> (so even plain text becomes valid XML)
				StringReader stringReader = new StringReader(string.Concat("<DIV>", text, "</DIV>"));

				// Read the input
				XmlReader xmlReader = XmlReader.Create(stringReader);

				// Read the entire XML DOM...
				while (xmlReader.Read())
				{
					string nameLower = xmlReader.Name.ToLower();
					if (xmlReader.NodeType == XmlNodeType.Element)
					{
						bool bEmpty = xmlReader.IsEmptyElement;

						// Handle the begin element
						switch (nameLower)
						{
							case "a":
							{
								if (bEmpty)
									break;

								FontProperties font = g_sFonts.Peek();
								if (xmlReader.MoveToFirstAttribute())
								do
								{
									if (xmlReader.Name.ToLower() == "href")
									{
										font.link = xmlReader.Value;
										font.underline = true;
										font.brush = Colors.Blue.ToBrush();
									}
								}
								while (xmlReader.MoveToNextAttribute());
								g_sFonts.Push(font);
								break;
							}

							case "font":
							{
								if (bEmpty)
									break;

								FontProperties font = g_sFonts.Peek();
								if (xmlReader.MoveToFirstAttribute())
								do
								{
									if (xmlReader.Name.ToLower() == "face")
										font.face = xmlReader.Value;
									if (xmlReader.Name.ToLower() == "size")
										font.size = Convert.ToDouble(xmlReader.Value);
									if (xmlReader.Name.ToLower() == "color")
										font.brush = xmlReader.Value.ToColor().ToBrush();
								}
								while (xmlReader.MoveToNextAttribute());
								g_sFonts.Push(font);
								break;
							}
							
							case "b":
							case "strong":
							{
								if (bEmpty)
									break;

								FontProperties font = g_sFonts.Peek();
								font.bold = true;
								g_sFonts.Push(font);
								break;
							}

							case "h1":
							case "h2":
							case "h3":
							case "h4":
							case "h5":
							case "h6":
							{
								textBlock.BreakAfterText();
								textBlock.StartNewParagraph();

								if (bEmpty)
									break;

								FontProperties font = g_sFonts.Peek();
								if (nameLower == "h1") font.size *= (24.0/12);	// xx-large	24pt	32pix
								if (nameLower == "h2") font.size *= (18.0/12);	// x-large	18pt	24pix
								if (nameLower == "h3") font.size *= (13.5/12);	// large	13.5pt	18pix
								if (nameLower == "h4") font.size *= (12.0/12);	// medium	12pt	16pix
								if (nameLower == "h5") font.size *= (10.5/12);	// sSmall	10.5pt	14pix
								if (nameLower == "h6") font.size *= ( 7.5/12);	// x-small	7.5pt	10pix
																				// xx-small	7.5pt	10pix
								font.bold = true;
								g_sFonts.Push(font);
								break;
							}

							case "i":
							case "em":
							case "cite":
							{
								if (bEmpty)
									break;

								FontProperties font = g_sFonts.Peek();
								font.italic = true;
								g_sFonts.Push(font);
								break;
							}

							case "u":
							{
								if (bEmpty)
									break;

								FontProperties font = g_sFonts.Peek();
								font.underline = true;
								g_sFonts.Push(font);
								break;
							}

							case "br":
							{
								textBlock.InlinesAdd(new LineBreak());
								break;
							}

							case "pre":
							{
								textBlock.BreakAfterText();
								textBlock.StartNewParagraph();

								if (bEmpty)
									break;

								FontProperties font = g_sFonts.Peek();
								font.face = "Courier New";
								g_sFonts.Push(font);
								break;
							}

							case "p":
							case "form":
							{
								textBlock.BreakAfterText();
								textBlock.StartNewParagraph();
								break;
							}

							case "ol":
							case "ul":
							case "dir":
							case "menu":
							{
								textBlock.BreakAfterText();

								FontProperties font = g_sFonts.Peek();
								if (bEmpty || font.listtype == 0)
									textBlock.StartNewParagraph();

								if (bEmpty)
									break;

								font.listtype = (nameLower == "ol" ? 1 : 2);
								font.listitems = 0;
								font.indent += 3;
								g_sFonts.Push(font);
								break;
							}

							case "li":
							{
								textBlock.BreakAfterText();
								if (bEmpty)
									break;

								FontProperties font = g_sFonts.Pop(); // Pop not Peek here
								font.listitems++;
								g_sFonts.Push(font);
								font.listitem = true;
								g_sFonts.Push(font);
								break;
							}

							case "div":
							case "center":
							{
								textBlock.BreakAfterText();
								break;
							}

							case "span":
							{
								break;
							}
						}
					}
					else
					if (xmlReader.NodeType == XmlNodeType.EndElement)
					{
						// Handle the end element
						switch (nameLower)
						{
							case "a":
							{
								g_sFonts.Pop();
								break;
							}

							case "font":
							{
								g_sFonts.Pop();
								break;
							}

							case "b":
							case "strong":
							{
								g_sFonts.Pop();
								break;
							}

							case "h1":
							case "h2":
							case "h3":
							case "h4":
							case "h5":
							case "h6":
							{
								textBlock.BreakAfterText();
								textBlock.StartNewParagraph();
								g_sFonts.Pop();
								break;
							}

							case "i":
							case "em":
							case "cite":
							{
								g_sFonts.Pop();
								break;
							}

							case "u":
							{
								g_sFonts.Pop();
								break;
							}

							case "br":
							{
								break;
							}

							case "pre":
							{
								textBlock.BreakAfterText();
								textBlock.StartNewParagraph();
								g_sFonts.Pop();
								break;
							}

							case "p":
							case "form":
							{
								textBlock.BreakAfterText();
								textBlock.StartNewParagraph();
								break;
							}

							case "ol":
							case "ul":
							case "dir":
							case "menu":
							{
								textBlock.BreakAfterText();

								FontProperties font = g_sFonts.Pop();
								if (font.listtype == 0)
									textBlock.StartNewParagraph();

								break;
							}

							case "li":
							{
								textBlock.BreakAfterText();
								g_sFonts.Pop();
								break;
							}

							case "div":
							case "center":
							{
								textBlock.BreakAfterText();
								break;
							}

							case "span":
							{
								break;
							}
						}
					}
					else
					if (xmlReader.NodeType == XmlNodeType.Text)
					{
						// Create a Run for the visible text
						// Collapse contiguous whitespace per HTML behavior
						StringBuilder builder = new StringBuilder(xmlReader.Value.Length);
						char cLast = (g_iPrevLineBreaks > 0 ? ' ' : '\0');
						foreach (char ch in xmlReader.Value)
						{
							char c = ch;
							if (c == '\t' || c == '\n') c = ' ';
							bool bSkip = (cLast == ' ' && c == ' ');
							cLast = c;
							if (!bSkip)
								builder.Append(c);
						}

						// If any text to display...
						string builderString = builder.ToString();
						if (builderString.Length > 0)
						{
							// Create a Run to display it
							Run run = new Run();
							run.Text = builderString;
							textBlock.InlinesAdd(run);
						}
					}
					else
					if (xmlReader.NodeType == XmlNodeType.Whitespace)
					{
					}
				}
			}
			catch (Exception e)
			{
				System.Diagnostics.Debug.WriteLine(e.Message);
				e.Assert();

				// Invalid XHTML
				textBlock.Inlines.Clear();
				textBlock.Text = text;
			}
		}
 public void Setup()
 {
     this.stack = new Stack();
 }