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
- ModuleConfigurationInfo.cs
- GridViewHeaderRowPresenter.cs
- ReflectionPermission.cs
- MouseCaptureWithinProperty.cs
- CodeTypeParameter.cs
- PersonalizableTypeEntry.cs
- DataGridViewLinkCell.cs
- HttpException.cs
- ExpressionUtilities.cs
- TogglePattern.cs
- RemotingServices.cs
- CharUnicodeInfo.cs
- tooltip.cs
- DataGridCommandEventArgs.cs
- RichTextBox.cs
- CmsUtils.cs
- Thread.cs
- CryptoConfig.cs
- MasterPageBuildProvider.cs
- SqlNodeAnnotations.cs
- DataTableReader.cs
- DataGridViewEditingControlShowingEventArgs.cs
- SimpleParser.cs
- Graphics.cs
- DictionaryEditChange.cs
- QueryCacheEntry.cs
- ProviderManager.cs
- PageHandlerFactory.cs
- CryptoApi.cs
- PersistenceMetadataNamespace.cs
- ConfigurationException.cs
- KeyConstraint.cs
- JoinSymbol.cs
- PassportAuthenticationEventArgs.cs
- FixedSOMTextRun.cs
- Hash.cs
- LineGeometry.cs
- NetPipeSection.cs
- BigInt.cs
- AsyncStreamReader.cs
- DiffuseMaterial.cs
- Rectangle.cs
- _BufferOffsetSize.cs
- PrintDocument.cs
- FunctionNode.cs
- NullableIntAverageAggregationOperator.cs
- ChooseAction.cs
- Track.cs
- ExpressionBindingsDialog.cs
- PropertyItemInternal.cs
- LiteralDesigner.cs
- DelegatingMessage.cs
- InternalEnumValidator.cs
- Polyline.cs
- MetaType.cs
- GlyphShapingProperties.cs
- DefaultMergeHelper.cs
- EntityTypeEmitter.cs
- EntitySqlQueryCacheEntry.cs
- RadioButtonPopupAdapter.cs
- TagNameToTypeMapper.cs
- xsdvalidator.cs
- CapabilitiesAssignment.cs
- ProfilePropertySettings.cs
- ReverseComparer.cs
- CollectionBase.cs
- WorkflowView.cs
- WebPartDisplayModeEventArgs.cs
- CaseExpr.cs
- ListViewGroupConverter.cs
- MultiPageTextView.cs
- BadImageFormatException.cs
- ToolStripLabel.cs
- SerializableAttribute.cs
- JsonWriter.cs
- RowCache.cs
- NamespaceEmitter.cs
- VectorValueSerializer.cs
- ValueProviderWrapper.cs
- DbConnectionOptions.cs
- LateBoundBitmapDecoder.cs
- FrameworkContextData.cs
- NameValuePermission.cs
- InternalTypeHelper.cs
- ToolStripItemImageRenderEventArgs.cs
- XhtmlBasicCommandAdapter.cs
- BoolExpressionVisitors.cs
- OleDbCommandBuilder.cs
- WSSecurityPolicy.cs
- _ListenerAsyncResult.cs
- AsyncContentLoadedEventArgs.cs
- ProfileSettingsCollection.cs
- QueryRewriter.cs
- RectValueSerializer.cs
- DragSelectionMessageFilter.cs
- TraceProvider.cs
- DesignerVerbToolStripMenuItem.cs
- XmlNodeReader.cs
- activationcontext.cs
- HtmlTextArea.cs