Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / MIT / System / Web / UI / MobileControls / LiteralTextParser.cs / 1305376 / LiteralTextParser.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- using System; using System.Collections; using System.Collections.Specialized; using System.Globalization; using System.Text; using System.Web; namespace System.Web.UI.MobileControls { /* * LiteralTextParser class. * * The LiteralTextParser class parses a string of literal text, * containing certain recognizable tags, and creates a set of controls * from them. Any unrecognized tags are ignored. * * This is an abstract base class. RuntimeLiteralTextParser and * CompileTimeLiteralTextParser inherit from this class. * * Copyright (c) 2000 Microsoft Corporation */ [Obsolete("The System.Web.Mobile.dll assembly has been deprecated and should no longer be used. For information about how to develop ASP.NET mobile applications, see http://go.microsoft.com/fwlink/?LinkId=157231.")] internal abstract class LiteralTextParser { // The parsing methods (Parse, ParseTag, ParseTagAttributes, ParseText) // build up LiteralElement objects, which can either be text or tags. // ProcessElementInternal is then called. It combines some other data // and calls ProcessElement, a method which is overridable by inherited // classes. // Literal Element type - includes recognized tags. protected enum LiteralElementType { Unrecognized, Text, Bold, Italic, Break, Paragraph, Anchor, } // Available formatting options for literal elements. This enum can // be combined with the | operator. protected enum LiteralFormat { None = 0, Bold = 1, Italic = 2, } // Literal Element. protected class LiteralElement { public LiteralElementType Type; public IDictionary Attributes; public String Text; public LiteralFormat Format = LiteralFormat.None; public bool BreakAfter = false; public bool ForceBreakTag = false; public LiteralElement(String text) { Type = LiteralElementType.Text; Attributes = null; Text = text; } public LiteralElement(LiteralElementType type, IDictionary attributes) { Type = type; Attributes = attributes; Text = String.Empty; } public bool IsText { get { return Type == LiteralElementType.Text; } } public bool IsEmptyText { get { return IsText && !LiteralTextParser.IsValidText(Text); } } public String GetAttribute(String attributeName) { Object o = (Attributes != null) ? Attributes[attributeName] : null; return (o != null) ? (String)o : String.Empty; } } // Methods overriden by inherited classes. protected abstract void ProcessElement(LiteralElement element); protected abstract void ProcessTagInnerText(String text); private bool _isBreakingReset = true; private LiteralElement _lastQueuedElement = null; private LiteralElement _currentTag = null; private bool _beginNewParagraph = true; private FormatStack _formatStack = new FormatStack(); private bool _elementsProcessed = false; // Static constructor that builds a lookup table of recognized tags. private static IDictionary _recognizedTags = new Hashtable(); static LiteralTextParser() { // PERF: Add both lowercase and uppercase. _recognizedTags.Add("b", LiteralElementType.Bold); _recognizedTags.Add("B", LiteralElementType.Bold); _recognizedTags.Add("i", LiteralElementType.Italic); _recognizedTags.Add("I", LiteralElementType.Italic); _recognizedTags.Add("br", LiteralElementType.Break); _recognizedTags.Add("BR", LiteralElementType.Break); _recognizedTags.Add("p", LiteralElementType.Paragraph); _recognizedTags.Add("P", LiteralElementType.Paragraph); _recognizedTags.Add("a", LiteralElementType.Anchor); _recognizedTags.Add("A", LiteralElementType.Anchor); } // Convert a tag name to a type. private static LiteralElementType TagNameToType(String tagName) { Object o = _recognizedTags[tagName]; if (o == null) { o = _recognizedTags[tagName.ToLower(CultureInfo.InvariantCulture)]; } return (o != null) ? (LiteralElementType)o : LiteralElementType.Unrecognized; } // Returns true if any valid controls could be generated from the given text. internal /*public*/ static bool IsValidText(String validText) { // if (validText.Length == 0) { return false; } foreach (char c in validText) { if (!Char.IsWhiteSpace(c) && c != '\t' && c != '\r' && c != '\n') { return true; } } return false; } // Main parse routine. Called with a block of text to parse. internal /*public*/ void Parse(String literalText) { int length = literalText.Length; int currentPosition = 0; while (currentPosition < length) { // Find start of next tag. int nextTag = literalText.IndexOf('<', currentPosition); if (nextTag == -1) { ParseText(literalText.Substring(currentPosition)); break; } if (nextTag > currentPosition) { ParseText(literalText.Substring(currentPosition, nextTag - currentPosition)); } // Find end of tag. char quoteChar = '\0'; int endOfTag; for (endOfTag = nextTag + 1; endOfTag < length; endOfTag++) { char c = literalText[endOfTag]; if (quoteChar == '\0') { if (c == '\'' || c == '\"') { quoteChar = c; } else if (c == '>') { break; } } else { if (c == quoteChar) { quoteChar = '\0'; } } } if (endOfTag == length) { // break; } ParseTag(literalText, nextTag + 1, endOfTag); currentPosition = endOfTag + 1; } Flush(); } internal /*public*/ void ResetBreaking() { _isBreakingReset = true; ElementsProcessed = false; } internal /*public*/ void ResetNewParagraph() { _beginNewParagraph = false; } internal /*public*/ void UnResetBreaking() { _isBreakingReset = false; } protected bool ElementsProcessed { get { return _elementsProcessed; } set { _elementsProcessed = value; } } protected void OnAfterDataBoundLiteral() { ElementsProcessed = true; UnResetBreaking(); } // Parse a single tag. private void ParseTag(String literalText, int tagStart, int tagFinish) { bool isClosingTag = (literalText[tagStart] == '/'); if (isClosingTag) { tagStart++; } // Empty tag? if (tagStart == tagFinish) { return; } // Look for end of tag name. int tagNameFinish = tagStart; while (tagNameFinish < tagFinish && !Char.IsWhiteSpace(literalText[tagNameFinish]) && literalText[tagNameFinish] != '/') { tagNameFinish++; } // Extract tag name, and compare to recognized tags. String tagName = literalText.Substring(tagStart, tagNameFinish - tagStart); LiteralElementType tagType = TagNameToType(tagName); if (tagType == LiteralElementType.Unrecognized) { return; } // Are we already in a complex tag? if (_currentTag != null) { // Ignore any inner tags, except the closing tag. if (_currentTag.Type == tagType && isClosingTag) { ProcessElementInternal(_currentTag); _currentTag = null; } else { // } return; } switch (tagType) { case LiteralElementType.Paragraph: // Do not create two breaks forpairs. if (!_isBreakingReset) { _isBreakingReset = true; goto case LiteralElementType.Break; } break; case LiteralElementType.Break: // If a break is already pending, insert an empty one. if (_beginNewParagraph) { ParseText(String.Empty); } if (_lastQueuedElement != null && _lastQueuedElement.Text.Length == 0) { _lastQueuedElement.ForceBreakTag = true; } _beginNewParagraph = true; break; case LiteralElementType.Bold: if (isClosingTag) { _formatStack.Pop(FormatStack.Bold); } else { _formatStack.Push(FormatStack.Bold); } break; case LiteralElementType.Italic: if (isClosingTag) { _formatStack.Pop(FormatStack.Italic); } else { _formatStack.Push(FormatStack.Italic); } break; default: { if (!isClosingTag) { IDictionary attribs = ParseTagAttributes(literalText, tagNameFinish, tagFinish, tagName); _currentTag = new LiteralElement(tagType, attribs); } break; } } if (_isBreakingReset && tagType != LiteralElementType.Paragraph) { _isBreakingReset = false; } } protected bool IsInTag { get { return _currentTag != null; } } protected LiteralFormat CurrentFormat { get { return _formatStack.CurrentFormat; } } // Parse attributes of a tag. private enum AttributeParseState { StartingAttributeName, ReadingAttributeName, ReadingEqualSign, StartingAttributeValue, ReadingAttributeValue, Error, } private IDictionary ParseTagAttributes(String literalText, int attrStart, int attrFinish, String tagName) { if (attrFinish > attrStart && literalText[attrFinish - 1] == '/') { attrFinish--; } IDictionary dictionary = null; int attrPos = attrStart; bool skipWhiteSpaces = true; int attrNameStart = 0; int attrNameFinish = 0; int attrValueStart = 0; char quoteChar = '\0'; AttributeParseState state = AttributeParseState.StartingAttributeName; while (attrPos <= attrFinish && state != AttributeParseState.Error) { char c = attrPos == attrFinish ? '\0' : literalText[attrPos]; if (skipWhiteSpaces) { if (Char.IsWhiteSpace(c)) { attrPos++; continue; } else { skipWhiteSpaces = false; } } switch (state) { case AttributeParseState.StartingAttributeName: if (c == '\0') { attrPos = attrFinish + 1; } else { attrNameStart = attrPos; state = AttributeParseState.ReadingAttributeName; } break; case AttributeParseState.ReadingAttributeName: if (c == '=' || Char.IsWhiteSpace(c)) { attrNameFinish = attrPos; skipWhiteSpaces = true; state = AttributeParseState.ReadingEqualSign; } else if (c == '\0') { state = AttributeParseState.Error; } else { attrPos++; } break; case AttributeParseState.ReadingEqualSign: if (c == '=') { skipWhiteSpaces = true; state = AttributeParseState.StartingAttributeValue; attrPos++; } else { state = AttributeParseState.Error; } break; case AttributeParseState.StartingAttributeValue: attrValueStart = attrPos; if (c == '\0') { state = AttributeParseState.Error; break; } else if (c == '\"' || c == '\'') { quoteChar = c; attrValueStart++; attrPos++; } else { quoteChar = '\0'; } state = AttributeParseState.ReadingAttributeValue; break; case AttributeParseState.ReadingAttributeValue: if (c == quoteChar || ((Char.IsWhiteSpace(c) || c == '\0') && quoteChar == '\0')) { if (attrNameFinish == attrNameStart) { state = AttributeParseState.Error; break; } if (dictionary == null) { dictionary = new HybridDictionary(true); } dictionary.Add( literalText.Substring(attrNameStart, attrNameFinish - attrNameStart), literalText.Substring(attrValueStart, attrPos - attrValueStart)); skipWhiteSpaces = true; state = AttributeParseState.StartingAttributeName; if (c == quoteChar) { attrPos++; } } else { attrPos++; } break; } } if (state == AttributeParseState.Error) { throw new Exception(SR.GetString(SR.LiteralTextParser_InvalidTagFormat)); } return dictionary; } // Parse a plain text literal. private void ParseText(String text) { if (_currentTag != null) { // Add to inner text of tag. _currentTag.Text += text; } else { if (_isBreakingReset && IsValidText(text)) { _isBreakingReset = false; } ProcessElementInternal(new LiteralElement(text)); } } private void ProcessElementInternal(LiteralElement element) { // This method needs to fill in an element with formatting and // breaking information, and calls ProcessElement. However, // each element needs to know whether there will be a break // AFTER the element, so elements are processed lazily, keeping // the last one in a single-element queue. LiteralFormat currentFormat = _formatStack.CurrentFormat; if (_lastQueuedElement != null) { // If both the last and current element are text elements, and // the formatting hasn't changed, then just combine the two into // a single element. if (_lastQueuedElement.IsText && element.IsText && (_lastQueuedElement.Format == currentFormat) && !_beginNewParagraph) { _lastQueuedElement.Text += element.Text; return; } else if (_lastQueuedElement.IsEmptyText && !_beginNewParagraph && IgnoreWhiteSpaceElement(_lastQueuedElement)) { // Empty text element with no breaks - so just ignore. } else { _lastQueuedElement.BreakAfter = _beginNewParagraph; ProcessElement(_lastQueuedElement); ElementsProcessed = true; } } _lastQueuedElement = element; _lastQueuedElement.Format = currentFormat; _beginNewParagraph = false; } private void Flush() { if (_currentTag != null) { // In the middle of a tag. There may be multiple inner text elements inside // a tag, e.g. // some text <%# a databinding %> some more text // and we're being flushed just at the start of the databinding. if (!_currentTag.IsEmptyText) { ProcessTagInnerText(_currentTag.Text); } _currentTag.Text = String.Empty; return; } if (_lastQueuedElement == null) { return; } // Ignore orphaned whitespace. if (!_lastQueuedElement.ForceBreakTag && _lastQueuedElement.IsEmptyText) { if (!ElementsProcessed) { return; } if (_lastQueuedElement.Text.Length == 0 || _lastQueuedElement.Text[0] != ' ') { return; } _lastQueuedElement.Text = " "; } _lastQueuedElement.BreakAfter = _beginNewParagraph; ProcessElement(_lastQueuedElement); _lastQueuedElement = null; } protected virtual bool IgnoreWhiteSpaceElement(LiteralElement element) { return true; } /* * FormatStack private class * * This class maintains a simple stack of formatting directives. As tags and * closing tags are processed, they are pushed on and popped off this stack. * The CurrentFormat property returns the current state. */ private class FormatStack { internal const char Bold = 'b'; internal const char Italic = 'i'; private StringBuilder _stringBuilder = new StringBuilder(16); public void Push(char option) { _stringBuilder.Append(option); } public void Pop(char option) { // Only pop a matching directive - non-matching directives are ignored! int length = _stringBuilder.Length; if (length > 0 && _stringBuilder[length - 1] == option) { _stringBuilder.Remove(length - 1, 1); } } public LiteralFormat CurrentFormat { get { LiteralFormat format = LiteralFormat.None; for (int i = _stringBuilder.Length - 1; i >= 0; i--) { switch (_stringBuilder[i]) { case Bold: format |= LiteralFormat.Bold; break; case Italic: format |= LiteralFormat.Italic; break; } } return format; } } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //------------------------------------------------------------------------------ //
// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- using System; using System.Collections; using System.Collections.Specialized; using System.Globalization; using System.Text; using System.Web; namespace System.Web.UI.MobileControls { /* * LiteralTextParser class. * * The LiteralTextParser class parses a string of literal text, * containing certain recognizable tags, and creates a set of controls * from them. Any unrecognized tags are ignored. * * This is an abstract base class. RuntimeLiteralTextParser and * CompileTimeLiteralTextParser inherit from this class. * * Copyright (c) 2000 Microsoft Corporation */ [Obsolete("The System.Web.Mobile.dll assembly has been deprecated and should no longer be used. For information about how to develop ASP.NET mobile applications, see http://go.microsoft.com/fwlink/?LinkId=157231.")] internal abstract class LiteralTextParser { // The parsing methods (Parse, ParseTag, ParseTagAttributes, ParseText) // build up LiteralElement objects, which can either be text or tags. // ProcessElementInternal is then called. It combines some other data // and calls ProcessElement, a method which is overridable by inherited // classes. // Literal Element type - includes recognized tags. protected enum LiteralElementType { Unrecognized, Text, Bold, Italic, Break, Paragraph, Anchor, } // Available formatting options for literal elements. This enum can // be combined with the | operator. protected enum LiteralFormat { None = 0, Bold = 1, Italic = 2, } // Literal Element. protected class LiteralElement { public LiteralElementType Type; public IDictionary Attributes; public String Text; public LiteralFormat Format = LiteralFormat.None; public bool BreakAfter = false; public bool ForceBreakTag = false; public LiteralElement(String text) { Type = LiteralElementType.Text; Attributes = null; Text = text; } public LiteralElement(LiteralElementType type, IDictionary attributes) { Type = type; Attributes = attributes; Text = String.Empty; } public bool IsText { get { return Type == LiteralElementType.Text; } } public bool IsEmptyText { get { return IsText && !LiteralTextParser.IsValidText(Text); } } public String GetAttribute(String attributeName) { Object o = (Attributes != null) ? Attributes[attributeName] : null; return (o != null) ? (String)o : String.Empty; } } // Methods overriden by inherited classes. protected abstract void ProcessElement(LiteralElement element); protected abstract void ProcessTagInnerText(String text); private bool _isBreakingReset = true; private LiteralElement _lastQueuedElement = null; private LiteralElement _currentTag = null; private bool _beginNewParagraph = true; private FormatStack _formatStack = new FormatStack(); private bool _elementsProcessed = false; // Static constructor that builds a lookup table of recognized tags. private static IDictionary _recognizedTags = new Hashtable(); static LiteralTextParser() { // PERF: Add both lowercase and uppercase. _recognizedTags.Add("b", LiteralElementType.Bold); _recognizedTags.Add("B", LiteralElementType.Bold); _recognizedTags.Add("i", LiteralElementType.Italic); _recognizedTags.Add("I", LiteralElementType.Italic); _recognizedTags.Add("br", LiteralElementType.Break); _recognizedTags.Add("BR", LiteralElementType.Break); _recognizedTags.Add("p", LiteralElementType.Paragraph); _recognizedTags.Add("P", LiteralElementType.Paragraph); _recognizedTags.Add("a", LiteralElementType.Anchor); _recognizedTags.Add("A", LiteralElementType.Anchor); } // Convert a tag name to a type. private static LiteralElementType TagNameToType(String tagName) { Object o = _recognizedTags[tagName]; if (o == null) { o = _recognizedTags[tagName.ToLower(CultureInfo.InvariantCulture)]; } return (o != null) ? (LiteralElementType)o : LiteralElementType.Unrecognized; } // Returns true if any valid controls could be generated from the given text. internal /*public*/ static bool IsValidText(String validText) { // if (validText.Length == 0) { return false; } foreach (char c in validText) { if (!Char.IsWhiteSpace(c) && c != '\t' && c != '\r' && c != '\n') { return true; } } return false; } // Main parse routine. Called with a block of text to parse. internal /*public*/ void Parse(String literalText) { int length = literalText.Length; int currentPosition = 0; while (currentPosition < length) { // Find start of next tag. int nextTag = literalText.IndexOf('<', currentPosition); if (nextTag == -1) { ParseText(literalText.Substring(currentPosition)); break; } if (nextTag > currentPosition) { ParseText(literalText.Substring(currentPosition, nextTag - currentPosition)); } // Find end of tag. char quoteChar = '\0'; int endOfTag; for (endOfTag = nextTag + 1; endOfTag < length; endOfTag++) { char c = literalText[endOfTag]; if (quoteChar == '\0') { if (c == '\'' || c == '\"') { quoteChar = c; } else if (c == '>') { break; } } else { if (c == quoteChar) { quoteChar = '\0'; } } } if (endOfTag == length) { // break; } ParseTag(literalText, nextTag + 1, endOfTag); currentPosition = endOfTag + 1; } Flush(); } internal /*public*/ void ResetBreaking() { _isBreakingReset = true; ElementsProcessed = false; } internal /*public*/ void ResetNewParagraph() { _beginNewParagraph = false; } internal /*public*/ void UnResetBreaking() { _isBreakingReset = false; } protected bool ElementsProcessed { get { return _elementsProcessed; } set { _elementsProcessed = value; } } protected void OnAfterDataBoundLiteral() { ElementsProcessed = true; UnResetBreaking(); } // Parse a single tag. private void ParseTag(String literalText, int tagStart, int tagFinish) { bool isClosingTag = (literalText[tagStart] == '/'); if (isClosingTag) { tagStart++; } // Empty tag? if (tagStart == tagFinish) { return; } // Look for end of tag name. int tagNameFinish = tagStart; while (tagNameFinish < tagFinish && !Char.IsWhiteSpace(literalText[tagNameFinish]) && literalText[tagNameFinish] != '/') { tagNameFinish++; } // Extract tag name, and compare to recognized tags. String tagName = literalText.Substring(tagStart, tagNameFinish - tagStart); LiteralElementType tagType = TagNameToType(tagName); if (tagType == LiteralElementType.Unrecognized) { return; } // Are we already in a complex tag? if (_currentTag != null) { // Ignore any inner tags, except the closing tag. if (_currentTag.Type == tagType && isClosingTag) { ProcessElementInternal(_currentTag); _currentTag = null; } else { // } return; } switch (tagType) { case LiteralElementType.Paragraph: // Do not create two breaks forpairs. if (!_isBreakingReset) { _isBreakingReset = true; goto case LiteralElementType.Break; } break; case LiteralElementType.Break: // If a break is already pending, insert an empty one. if (_beginNewParagraph) { ParseText(String.Empty); } if (_lastQueuedElement != null && _lastQueuedElement.Text.Length == 0) { _lastQueuedElement.ForceBreakTag = true; } _beginNewParagraph = true; break; case LiteralElementType.Bold: if (isClosingTag) { _formatStack.Pop(FormatStack.Bold); } else { _formatStack.Push(FormatStack.Bold); } break; case LiteralElementType.Italic: if (isClosingTag) { _formatStack.Pop(FormatStack.Italic); } else { _formatStack.Push(FormatStack.Italic); } break; default: { if (!isClosingTag) { IDictionary attribs = ParseTagAttributes(literalText, tagNameFinish, tagFinish, tagName); _currentTag = new LiteralElement(tagType, attribs); } break; } } if (_isBreakingReset && tagType != LiteralElementType.Paragraph) { _isBreakingReset = false; } } protected bool IsInTag { get { return _currentTag != null; } } protected LiteralFormat CurrentFormat { get { return _formatStack.CurrentFormat; } } // Parse attributes of a tag. private enum AttributeParseState { StartingAttributeName, ReadingAttributeName, ReadingEqualSign, StartingAttributeValue, ReadingAttributeValue, Error, } private IDictionary ParseTagAttributes(String literalText, int attrStart, int attrFinish, String tagName) { if (attrFinish > attrStart && literalText[attrFinish - 1] == '/') { attrFinish--; } IDictionary dictionary = null; int attrPos = attrStart; bool skipWhiteSpaces = true; int attrNameStart = 0; int attrNameFinish = 0; int attrValueStart = 0; char quoteChar = '\0'; AttributeParseState state = AttributeParseState.StartingAttributeName; while (attrPos <= attrFinish && state != AttributeParseState.Error) { char c = attrPos == attrFinish ? '\0' : literalText[attrPos]; if (skipWhiteSpaces) { if (Char.IsWhiteSpace(c)) { attrPos++; continue; } else { skipWhiteSpaces = false; } } switch (state) { case AttributeParseState.StartingAttributeName: if (c == '\0') { attrPos = attrFinish + 1; } else { attrNameStart = attrPos; state = AttributeParseState.ReadingAttributeName; } break; case AttributeParseState.ReadingAttributeName: if (c == '=' || Char.IsWhiteSpace(c)) { attrNameFinish = attrPos; skipWhiteSpaces = true; state = AttributeParseState.ReadingEqualSign; } else if (c == '\0') { state = AttributeParseState.Error; } else { attrPos++; } break; case AttributeParseState.ReadingEqualSign: if (c == '=') { skipWhiteSpaces = true; state = AttributeParseState.StartingAttributeValue; attrPos++; } else { state = AttributeParseState.Error; } break; case AttributeParseState.StartingAttributeValue: attrValueStart = attrPos; if (c == '\0') { state = AttributeParseState.Error; break; } else if (c == '\"' || c == '\'') { quoteChar = c; attrValueStart++; attrPos++; } else { quoteChar = '\0'; } state = AttributeParseState.ReadingAttributeValue; break; case AttributeParseState.ReadingAttributeValue: if (c == quoteChar || ((Char.IsWhiteSpace(c) || c == '\0') && quoteChar == '\0')) { if (attrNameFinish == attrNameStart) { state = AttributeParseState.Error; break; } if (dictionary == null) { dictionary = new HybridDictionary(true); } dictionary.Add( literalText.Substring(attrNameStart, attrNameFinish - attrNameStart), literalText.Substring(attrValueStart, attrPos - attrValueStart)); skipWhiteSpaces = true; state = AttributeParseState.StartingAttributeName; if (c == quoteChar) { attrPos++; } } else { attrPos++; } break; } } if (state == AttributeParseState.Error) { throw new Exception(SR.GetString(SR.LiteralTextParser_InvalidTagFormat)); } return dictionary; } // Parse a plain text literal. private void ParseText(String text) { if (_currentTag != null) { // Add to inner text of tag. _currentTag.Text += text; } else { if (_isBreakingReset && IsValidText(text)) { _isBreakingReset = false; } ProcessElementInternal(new LiteralElement(text)); } } private void ProcessElementInternal(LiteralElement element) { // This method needs to fill in an element with formatting and // breaking information, and calls ProcessElement. However, // each element needs to know whether there will be a break // AFTER the element, so elements are processed lazily, keeping // the last one in a single-element queue. LiteralFormat currentFormat = _formatStack.CurrentFormat; if (_lastQueuedElement != null) { // If both the last and current element are text elements, and // the formatting hasn't changed, then just combine the two into // a single element. if (_lastQueuedElement.IsText && element.IsText && (_lastQueuedElement.Format == currentFormat) && !_beginNewParagraph) { _lastQueuedElement.Text += element.Text; return; } else if (_lastQueuedElement.IsEmptyText && !_beginNewParagraph && IgnoreWhiteSpaceElement(_lastQueuedElement)) { // Empty text element with no breaks - so just ignore. } else { _lastQueuedElement.BreakAfter = _beginNewParagraph; ProcessElement(_lastQueuedElement); ElementsProcessed = true; } } _lastQueuedElement = element; _lastQueuedElement.Format = currentFormat; _beginNewParagraph = false; } private void Flush() { if (_currentTag != null) { // In the middle of a tag. There may be multiple inner text elements inside // a tag, e.g. // some text <%# a databinding %> some more text // and we're being flushed just at the start of the databinding. if (!_currentTag.IsEmptyText) { ProcessTagInnerText(_currentTag.Text); } _currentTag.Text = String.Empty; return; } if (_lastQueuedElement == null) { return; } // Ignore orphaned whitespace. if (!_lastQueuedElement.ForceBreakTag && _lastQueuedElement.IsEmptyText) { if (!ElementsProcessed) { return; } if (_lastQueuedElement.Text.Length == 0 || _lastQueuedElement.Text[0] != ' ') { return; } _lastQueuedElement.Text = " "; } _lastQueuedElement.BreakAfter = _beginNewParagraph; ProcessElement(_lastQueuedElement); _lastQueuedElement = null; } protected virtual bool IgnoreWhiteSpaceElement(LiteralElement element) { return true; } /* * FormatStack private class * * This class maintains a simple stack of formatting directives. As tags and * closing tags are processed, they are pushed on and popped off this stack. * The CurrentFormat property returns the current state. */ private class FormatStack { internal const char Bold = 'b'; internal const char Italic = 'i'; private StringBuilder _stringBuilder = new StringBuilder(16); public void Push(char option) { _stringBuilder.Append(option); } public void Pop(char option) { // Only pop a matching directive - non-matching directives are ignored! int length = _stringBuilder.Length; if (length > 0 && _stringBuilder[length - 1] == option) { _stringBuilder.Remove(length - 1, 1); } } public LiteralFormat CurrentFormat { get { LiteralFormat format = LiteralFormat.None; for (int i = _stringBuilder.Length - 1; i >= 0; i--) { switch (_stringBuilder[i]) { case Bold: format |= LiteralFormat.Bold; break; case Italic: format |= LiteralFormat.Italic; break; } } return format; } } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- SortDescriptionCollection.cs
- BinaryObjectInfo.cs
- OracleRowUpdatedEventArgs.cs
- CallContext.cs
- ArcSegment.cs
- JavaScriptString.cs
- InstanceLockException.cs
- EncoderNLS.cs
- xsdvalidator.cs
- XmlHierarchyData.cs
- Visitor.cs
- CellParagraph.cs
- DataContractSet.cs
- CodeSpit.cs
- WebPartDisplayModeCollection.cs
- GeneralTransform3DTo2D.cs
- ImageFormatConverter.cs
- CodeGenerationManager.cs
- AllMembershipCondition.cs
- IgnoreDeviceFilterElement.cs
- WebScriptServiceHostFactory.cs
- MasterPageParser.cs
- FieldNameLookup.cs
- AutoGeneratedFieldProperties.cs
- FixedTextView.cs
- cryptoapiTransform.cs
- SamlConditions.cs
- RootBrowserWindow.cs
- WizardPanel.cs
- EndOfStreamException.cs
- RequestDescription.cs
- ProfileBuildProvider.cs
- XmlDownloadManager.cs
- EmptyEnumerator.cs
- CheckStoreFileValidityRequest.cs
- DynamicValueConverter.cs
- XmlFormatExtensionPrefixAttribute.cs
- Activation.cs
- IndexedEnumerable.cs
- ComplexObject.cs
- KnownBoxes.cs
- ExtensionQuery.cs
- Normalization.cs
- TextParagraph.cs
- DataErrorValidationRule.cs
- RuleInfoComparer.cs
- XmlEncoding.cs
- WindowsTokenRoleProvider.cs
- Span.cs
- ReversePositionQuery.cs
- ApplicationProxyInternal.cs
- XPathAncestorIterator.cs
- DbDataAdapter.cs
- ObjectItemCollectionAssemblyCacheEntry.cs
- FrameDimension.cs
- TouchPoint.cs
- AutomationProperty.cs
- CodeTypeConstructor.cs
- VerificationAttribute.cs
- NCryptNative.cs
- Focus.cs
- ObjectListSelectEventArgs.cs
- ProfileParameter.cs
- Overlapped.cs
- TextOutput.cs
- BaseHashHelper.cs
- ResourceContainer.cs
- DataGridCellEditEndingEventArgs.cs
- FileDialogCustomPlace.cs
- CounterCreationDataCollection.cs
- SymmetricAlgorithm.cs
- ManagedFilter.cs
- EventListener.cs
- FlowDocumentFormatter.cs
- KeyInfo.cs
- DictionaryContent.cs
- COM2Enum.cs
- EmptyControlCollection.cs
- MaskPropertyEditor.cs
- securitymgrsite.cs
- QuadraticBezierSegment.cs
- CheckBox.cs
- Configuration.cs
- DataGridRelationshipRow.cs
- EncryptedXml.cs
- DataErrorValidationRule.cs
- GridView.cs
- BitConverter.cs
- EpmContentDeSerializer.cs
- StateBag.cs
- XmlImplementation.cs
- PassportAuthenticationEventArgs.cs
- Bezier.cs
- Int64Converter.cs
- SqlDataAdapter.cs
- XmlILOptimizerVisitor.cs
- Utils.cs
- CompilationUtil.cs
- DictionaryBase.cs
- OdbcEnvironmentHandle.cs