/// <summary>
        /// Parses a Knockout begin containerless comment
        /// </summary>
        /// <param name="commentText">Comment text</param>
        /// <param name="expressionHandler">Binding expression handler</param>
        public static void ParseBeginContainerlessComment(string commentText,
			ExpressionDelegate expressionHandler)
        {
            Match koBeginContainerlessCommentMatch = _koBeginContainerlessCommentRegex.Match(commentText);

            if (koBeginContainerlessCommentMatch.Success)
            {
                var innerContext = new InnerMarkupParsingContext(commentText);
                var context = new MarkupParsingContext(innerContext);

                Group expressionGroup = koBeginContainerlessCommentMatch.Groups["expression"];
                int expressionPosition = expressionGroup.Index;
                string expression = expressionGroup.Value.TrimEnd();

                innerContext.IncreasePosition(expressionPosition);

                if (expressionHandler != null)
                {
                    expressionHandler(context, expression);
                }
            }
        }
Exemple #2
0
        /// <summary>
        /// Parses XML content
        /// </summary>
        /// <param name="content">XML content</param>
        public void Parse(string content)
        {
            int contentLength = content.Length;
            if (contentLength == 0)
            {
                return;
            }

            lock (_parsingSynchronizer)
            {
                _innerContext = new InnerMarkupParsingContext(content);
                _context = new MarkupParsingContext(_innerContext);

                int endPosition = contentLength - 1;
                int previousPosition = -1;

                try
                {
                    while (_innerContext.Position <= endPosition)
                    {
                        bool isProcessed = false;
                        int firstCharPosition = _innerContext.Position;
                        char firstCharValue;
                        bool firstCharExist = content.TryGetChar(firstCharPosition, out firstCharValue);

                        if (firstCharExist && firstCharValue == '<')
                        {
                            int secondCharPosition = firstCharPosition + 1;
                            char secondCharValue;
                            bool secondCharExist = content.TryGetChar(secondCharPosition, out secondCharValue);

                            if (secondCharExist)
                            {
                                if (IsTagFirstChar(secondCharValue))
                                {
                                    // Start tag
                                    isProcessed = ProcessStartTag();
                                }
                                else
                                {
                                    int thirdCharPosition = secondCharPosition + 1;
                                    char thirdCharValue;
                                    bool thirdCharExist = content.TryGetChar(thirdCharPosition, out thirdCharValue);

                                    if (thirdCharExist)
                                    {
                                        switch (secondCharValue)
                                        {
                                            case '/':
                                                if (IsTagFirstChar(thirdCharValue))
                                                {
                                                    // End tag
                                                    isProcessed = ProcessEndTag();
                                                }
                                                break;

                                            case '!':
                                                switch (thirdCharValue)
                                                {
                                                    case '-':
                                                        int fourthCharPosition = thirdCharPosition + 1;
                                                        char fourthCharValue;
                                                        bool fourthCharExist = content.TryGetChar(
                                                            fourthCharPosition, out fourthCharValue);

                                                        if (fourthCharExist && fourthCharValue == '-')
                                                        {
                                                            // XML comments
                                                            isProcessed = ProcessComment();
                                                        }
                                                        break;

                                                    case '[':
                                                        // CDATA sections
                                                        isProcessed = ProcessCdataSection();
                                                        break;

                                                    case 'D':
                                                    case 'd':
                                                        // Doctype declaration
                                                        isProcessed = ProcessDoctype();
                                                        break;
                                                }
                                                break;

                                            case '?':
                                                // XML declaration and processing instructions
                                                isProcessed = ProcessProcessingInstruction();
                                                break;
                                        }
                                    }
                                }
                            }
                        }

                        if (!isProcessed)
                        {
                            // Text
                            ProcessText();
                        }

                        if (_innerContext.Position == previousPosition)
                        {
                            throw new MarkupParsingException(
                                string.Format(Strings.ErrorMessage_MarkupParsingFailed, "XML"),
                                _innerContext.NodeCoordinates, _innerContext.GetSourceFragment());
                        }

                        previousPosition = _innerContext.Position;
                    }

                    // Check whether there were not closed tags
                    if (_tagStack.Count > 0)
                    {
                        StackedXmlTag stackedTag = _tagStack.Pop();

                        throw new MarkupParsingException(
                            string.Format(Strings.ErrorMessage_NotClosedTag, stackedTag.Name),
                            stackedTag.Coordinates,
                            SourceCodeNavigator.GetSourceFragment(_innerContext.SourceCode, stackedTag.Coordinates));
                    }
                }
                catch (MarkupParsingException)
                {
                    throw;
                }
                finally
                {
                    _tagStack.Clear();

                    _context = null;
                    _innerContext = null;
                }
            }
        }
        /// <summary>
        /// Parses a Angular comment directive
        /// </summary>
        /// <param name="commentText">Comment text</param>
        /// <param name="directiveNameHandler">Directive name handler</param>
        /// <param name="expressionHandler">Binding expression handler</param>
        public static void ParseCommentDirective(string commentText, DirectiveNameDelegate directiveNameHandler,
			ExpressionDelegate expressionHandler)
        {
            Match ngCommentDirectiveMatch = _ngCommentDirectiveRegex.Match(commentText);

            if (ngCommentDirectiveMatch.Success)
            {
                var innerContext = new InnerMarkupParsingContext(commentText);
                var context = new MarkupParsingContext(innerContext);

                GroupCollection groups = ngCommentDirectiveMatch.Groups;

                Group directiveNameGroup = groups["directiveName"];
                int directiveNamePosition = directiveNameGroup.Index;
                string originalDirectiveName = directiveNameGroup.Value;
                string normalizedDirectiveName = NormalizeDirectiveName(originalDirectiveName);

                innerContext.IncreasePosition(directiveNamePosition);

                if (directiveNameHandler != null)
                {
                    directiveNameHandler(context, originalDirectiveName, normalizedDirectiveName);
                }

                Group expressionGroup = groups["expression"];
                if (expressionGroup.Success)
                {
                    int expressionPosition = expressionGroup.Index;
                    string expression = expressionGroup.Value.Trim();

                    innerContext.IncreasePosition(expressionPosition - directiveNamePosition);

                    if (expressionHandler != null)
                    {
                        expressionHandler(context, expression);
                    }
                }
            }
        }
        /// <summary>
        /// Parses a Angular class directive
        /// </summary>
        /// <param name="className">Class name</param>
        /// <param name="directiveNameHandler">Directive name handler</param>
        /// <param name="expressionHandler">Binding expression handler</param>
        /// <param name="semicolonHandler">Semicolon handler</param>
        public static void ParseClassDirective(string className, DirectiveNameDelegate directiveNameHandler,
			ExpressionDelegate expressionHandler, SemicolonDelegate semicolonHandler)
        {
            MatchCollection ngClassDirectiveMatches = _ngClassDirectiveRegex.Matches(className);

            if (ngClassDirectiveMatches.Count > 0)
            {
                var innerContext = new InnerMarkupParsingContext(className);
                var context = new MarkupParsingContext(innerContext);
                int currentPosition = 0;

                foreach (Match ngClassDirectiveMatch in ngClassDirectiveMatches)
                {
                    GroupCollection groups = ngClassDirectiveMatch.Groups;

                    Group directiveNameGroup = groups["directiveName"];
                    int directiveNamePosition = directiveNameGroup.Index;
                    string originalDirectiveName = directiveNameGroup.Value;
                    string normalizedDirectiveName = NormalizeDirectiveName(originalDirectiveName);

                    innerContext.IncreasePosition(directiveNamePosition - currentPosition);
                    currentPosition = directiveNamePosition;

                    if (directiveNameHandler != null)
                    {
                        directiveNameHandler(context, originalDirectiveName, normalizedDirectiveName);
                    }

                    Group expressionGroup = groups["expression"];
                    if (expressionGroup.Success)
                    {
                        int expressionPosition = expressionGroup.Index;
                        string expression = expressionGroup.Value.Trim();

                        innerContext.IncreasePosition(expressionPosition - currentPosition);
                        currentPosition = expressionPosition;

                        if (expressionHandler != null)
                        {
                            expressionHandler(context, expression);
                        }
                    }

                    Group semicolonGroup = groups["semicolon"];
                    if (semicolonGroup.Success)
                    {
                        int semicolonPosition = semicolonGroup.Index;

                        innerContext.IncreasePosition(semicolonPosition - currentPosition);
                        currentPosition = semicolonPosition;

                        if (semicolonHandler != null)
                        {
                            semicolonHandler(context);
                        }
                    }
                }
            }
        }
		/// <summary>
		/// Constructs instance of markup parsing context
		/// </summary>
		/// <param name="innerContext">Inner markup parsing context</param>
		internal MarkupParsingContext(InnerMarkupParsingContext innerContext)
		{
			_innerContext = innerContext;
		}
Exemple #6
0
        /// <summary>
        /// Parses HTML content
        /// </summary>
        /// <param name="content">HTML content</param>
        public void Parse(string content)
        {
            int contentLength = content.Length;
            if (contentLength == 0)
            {
                return;
            }

            lock (_parsingSynchronizer)
            {
                _innerContext = new InnerMarkupParsingContext(content);
                _context = new MarkupParsingContext(_innerContext);

                int endPosition = contentLength - 1;
                int previousPosition = -1;

                try
                {
                    while (_innerContext.Position <= endPosition)
                    {
                        bool isProcessed = false;
                        HtmlTag lastStackedTag = _tagStack.LastOrDefault();

                        // Make sure we're not in a tag, that contains embedded code
                        if (lastStackedTag == null || !lastStackedTag.Flags.HasFlag(HtmlTagFlags.EmbeddedCode))
                        {
                            int firstCharPosition = _innerContext.Position;
                            char firstCharValue;
                            bool firstCharExist = content.TryGetChar(firstCharPosition, out firstCharValue);

                            if (firstCharExist && firstCharValue == '<')
                            {
                                int secondCharPosition = firstCharPosition + 1;
                                char secondCharValue;
                                bool secondCharExist = content.TryGetChar(secondCharPosition, out secondCharValue);

                                if (secondCharExist)
                                {
                                    if (secondCharValue.IsAlphaNumeric())
                                    {
                                        // Start tag
                                        isProcessed = ProcessStartTag();
                                    }
                                    else
                                    {
                                        int thirdCharPosition = secondCharPosition + 1;
                                        char thirdCharValue;
                                        bool thirdCharExist = content.TryGetChar(thirdCharPosition, out thirdCharValue);

                                        if (thirdCharExist)
                                        {
                                            switch (secondCharValue)
                                            {
                                                case '/':
                                                    if (thirdCharValue.IsAlphaNumeric())
                                                    {
                                                        isProcessed = ProcessEndTag();
                                                    }
                                                    break;

                                                case '!':
                                                    switch (thirdCharValue)
                                                    {
                                                        case '-':
                                                            int fourthCharPosition = thirdCharPosition + 1;
                                                            char fourthCharValue;
                                                            bool fourthCharExist = content.TryGetChar(fourthCharPosition, out fourthCharValue);

                                                            if (fourthCharExist && fourthCharValue == '-')
                                                            {
                                                                // Comments
                                                                int fifthCharPosition = fourthCharPosition + 1;
                                                                char fifthCharValue;
                                                                bool fifthCharExist = content.TryGetChar(fifthCharPosition, out fifthCharValue);

                                                                if (fifthCharExist)
                                                                {
                                                                    if (fifthCharValue == '[')
                                                                    {
                                                                        // Revealed validating If conditional comments
                                                                        // (e.g. <!--[if ... ]><!--> or <!--[if ... ]>-->)
                                                                        isProcessed = ProcessRevealedValidatingIfComment();

                                                                        if (!isProcessed)
                                                                        {
                                                                            // Hidden If conditional comments (e.g. <!--[if ... ]>)
                                                                            isProcessed = ProcessHiddenIfComment();
                                                                        }
                                                                    }
                                                                    else
                                                                    {
                                                                        // Revealed validating End If conditional comments
                                                                        // (e.g. <!--<![endif]-->)
                                                                        isProcessed = ProcessRevealedValidatingEndIfComment();
                                                                    }
                                                                }

                                                                if (!isProcessed)
                                                                {
                                                                    // HTML comments
                                                                    isProcessed = ProcessComment();
                                                                }
                                                            }
                                                            break;

                                                        case '[':
                                                            // Remaining conditional comments

                                                            // Hidden End If conditional comment (e.g. <![endif]-->)
                                                            isProcessed = ProcessHiddenEndIfComment();

                                                            if (!isProcessed)
                                                            {
                                                                // Revealed If conditional comment (e.g. <![if ... ]>)
                                                                isProcessed = ProcessRevealedIfComment();
                                                            }

                                                            if (!isProcessed)
                                                            {
                                                                // Revealed End If conditional comment (e.g. <![endif]>)
                                                                isProcessed = ProcessRevealedEndIfComment();
                                                            }
                                                            break;

                                                        case 'D':
                                                        case 'd':
                                                            // Doctype declaration
                                                            isProcessed = ProcessDoctype();
                                                            break;
                                                    }
                                                    break;

                                                case '?':
                                                    // XML declaration
                                                    isProcessed = ProcessXmlDeclaration();
                                                    break;
                                            }
                                        }
                                    }
                                }
                            }

                            if (!isProcessed)
                            {
                                // Text
                                ProcessText();
                            }
                        }
                        else
                        {
                            // Embedded code
                            ProcessEmbeddedCode();
                        }

                        if (_innerContext.Position == previousPosition)
                        {
                            throw new MarkupParsingException(
                                string.Format(Strings.ErrorMessage_MarkupParsingFailed, "HTML"),
                                _innerContext.NodeCoordinates, _innerContext.GetSourceFragment());
                        }

                        previousPosition = _innerContext.Position;
                    }

                    // Clean up any remaining tags
                    ParseEndTag();

                    // Check whether there were not closed conditional comment
                    if (_conditionalCommentStack.Count > 0)
                    {
                        throw new MarkupParsingException(
                            Strings.ErrorMessage_NotClosedConditionalComment,
                            _innerContext.NodeCoordinates, _innerContext.GetSourceFragment());
                    }
                }
                catch (MarkupParsingException)
                {
                    throw;
                }
                finally
                {
                    _tagStack.Clear();
                    _htmlTagFlagsCache.Clear();
                    _customHtmlTagFlagsCache.Clear();
                    _conditionalCommentStack.Clear();
                    _conditionalCommentOpened = false;
                    _xmlTagStack.Clear();
                    _context = null;
                    _innerContext = null;
                }
            }
        }
        /// <summary>
        /// Parses XML content
        /// </summary>
        /// <param name="content">XML content</param>
        public void Parse(string content)
        {
            int contentLength = content.Length;
            if (contentLength == 0)
            {
                return;
            }

            lock (_parsingSynchronizer)
            {
                _innerContext = new InnerMarkupParsingContext(content);
                _context = new MarkupParsingContext(_innerContext);

                _tagStack = new Stack<StackedXmlTag>();

                int endPosition = contentLength - 1;
                int previousPosition = -1;

                try
                {
                    while (_innerContext.Position <= endPosition)
                    {
                        bool isProcessed = false;

                        if (content.CustomStartsWith("<", _innerContext.Position, StringComparison.Ordinal))
                        {
                            if (content.CustomStartsWith("</", _innerContext.Position, StringComparison.Ordinal))
                            {
                                // End tag
                                isProcessed = ProcessEndTag();
                            }
                            else if (content.CustomStartsWith("<!", _innerContext.Position, StringComparison.Ordinal))
                            {
                                // XML comments
                                isProcessed = ProcessComment();

                                if (!isProcessed)
                                {
                                    // CDATA sections
                                    isProcessed = ProcessCdataSection();
                                }

                                if (!isProcessed)
                                {
                                    // Doctype declaration
                                    isProcessed = ProcessDoctype();
                                }
                            }
                            else if (content.CustomStartsWith("<?", _innerContext.Position, StringComparison.Ordinal))
                            {
                                // XML declaration and processing instructions
                                isProcessed = ProcessProcessingInstruction();
                            }
                            else
                            {
                                // Start tag
                                isProcessed = ProcessStartTag();
                            }
                        }

                        if (!isProcessed)
                        {
                            // Text
                            ProcessText();
                        }

                        if (_innerContext.Position == previousPosition)
                        {
                            throw new XmlParsingException(
                                string.Format(Strings.ErrorMessage_MarkupParsingFailed, "XML"),
                                _innerContext.NodeCoordinates, _innerContext.GetSourceFragment());
                        }

                        previousPosition = _innerContext.Position;
                    }

                    // Check whether there were not closed tags
                    if (_tagStack.Count > 0)
                    {
                        StackedXmlTag stackedTag = _tagStack.Pop();

                        throw new XmlParsingException(
                            string.Format(Strings.ErrorMessage_NotClosedTag, stackedTag.Name),
                            stackedTag.Coordinates,
                            SourceCodeNavigator.GetSourceFragment(_innerContext.SourceCode, stackedTag.Coordinates));
                    }
                }
                catch (XmlParsingException)
                {
                    throw;
                }
                finally
                {
                    _tagStack.Clear();

                    _context = null;
                    _innerContext = null;
                }
            }
        }
        /// <summary>
        /// Parses a Mustache-style markup
        /// </summary>
        /// <param name="content">Mustache-style markup</param>
        /// <param name="mustacheStyleTagHandler">Mustache-style tags handler</param>
        /// <param name="textHandler">Text handler</param>
        public static void ParseMarkup(string content, MustacheStyleTagDelegate mustacheStyleTagHandler,
			TextDelegate textHandler)
        {
            var innerContext = new InnerMarkupParsingContext(content);
            var context = new MarkupParsingContext(innerContext);

            MatchCollection mustacheStyleTagMatches = _mustacheStyleTagRegex.Matches(content);
            if (mustacheStyleTagMatches.Count == 0)
            {
                if (textHandler != null)
                {
                    textHandler(context, content);
                }

                innerContext.IncreasePosition(content.Length);

                return;
            }

            int currentPosition = 0;
            int endPosition = content.Length - 1;

            foreach (Match mustacheStyleTagMatch in mustacheStyleTagMatches)
            {
                int mustacheStyleTagPosition = mustacheStyleTagMatch.Index;
                int mustacheStyleTagLength = mustacheStyleTagMatch.Length;

                if (mustacheStyleTagPosition > currentPosition)
                {
                    string text = content.Substring(currentPosition, mustacheStyleTagPosition - currentPosition);

                    if (textHandler != null)
                    {
                        textHandler(context, text);
                    }

                    innerContext.IncreasePosition(text.Length);
                }

                GroupCollection mustacheStyleTagGroups = mustacheStyleTagMatch.Groups;

                string expression = mustacheStyleTagGroups["expression"].Value;
                string startDelimiter = mustacheStyleTagGroups["startDelimiter"].Value;
                string endDelimiter = mustacheStyleTagGroups["endDelimiter"].Value;

                if (expression.StartsWith("{") && expression.EndsWith("}"))
                {
                    expression = expression.Substring(1, expression.Length - 2);
                    startDelimiter = "{{{";
                    endDelimiter = "}}}";
                }

                if (mustacheStyleTagHandler != null)
                {
                    mustacheStyleTagHandler(context, expression, startDelimiter, endDelimiter);
                }

                innerContext.IncreasePosition(mustacheStyleTagLength);
                currentPosition = mustacheStyleTagPosition + mustacheStyleTagLength;
            }

            if (currentPosition > 0 && currentPosition <= endPosition)
            {
                string text = content.Substring(currentPosition, endPosition - currentPosition + 1);

                if (textHandler != null)
                {
                    textHandler(context, text);
                }

                innerContext.IncreasePosition(text.Length);
            }
        }
Exemple #9
0
        /// <summary>
        /// Parses XML content
        /// </summary>
        /// <param name="content">XML content</param>
        public void Parse(string content)
        {
            int contentLength = content.Length;

            if (contentLength == 0)
            {
                return;
            }

            lock (_parsingSynchronizer)
            {
                _innerContext = new InnerMarkupParsingContext(content);
                _context      = new MarkupParsingContext(_innerContext);

                _tagStack = new Stack <StackedXmlTag>();

                int endPosition      = contentLength - 1;
                int previousPosition = -1;

                try
                {
                    while (_innerContext.Position <= endPosition)
                    {
                        bool isProcessed = false;

                        if (content.CustomStartsWith("<", _innerContext.Position, StringComparison.Ordinal))
                        {
                            if (content.CustomStartsWith("</", _innerContext.Position, StringComparison.Ordinal))
                            {
                                // End tag
                                isProcessed = ProcessEndTag();
                            }
                            else if (content.CustomStartsWith("<!", _innerContext.Position, StringComparison.Ordinal))
                            {
                                // XML comments
                                isProcessed = ProcessComment();

                                if (!isProcessed)
                                {
                                    // CDATA sections
                                    isProcessed = ProcessCdataSection();
                                }

                                if (!isProcessed)
                                {
                                    // Doctype declaration
                                    isProcessed = ProcessDoctype();
                                }
                            }
                            else if (content.CustomStartsWith("<?", _innerContext.Position, StringComparison.Ordinal))
                            {
                                // XML declaration and processing instructions
                                isProcessed = ProcessProcessingInstruction();
                            }
                            else
                            {
                                // Start tag
                                isProcessed = ProcessStartTag();
                            }
                        }

                        if (!isProcessed)
                        {
                            // Text
                            ProcessText();
                        }

                        if (_innerContext.Position == previousPosition)
                        {
                            throw new XmlParsingException(
                                      string.Format(Strings.ErrorMessage_MarkupParsingFailed, "XML"),
                                      _innerContext.NodeCoordinates, _innerContext.GetSourceFragment());
                        }

                        previousPosition = _innerContext.Position;
                    }

                    // Check whether there were not closed tags
                    if (_tagStack.Count > 0)
                    {
                        StackedXmlTag stackedTag = _tagStack.Pop();

                        throw new XmlParsingException(
                                  string.Format(Strings.ErrorMessage_NotClosedTag, stackedTag.Name),
                                  stackedTag.Coordinates,
                                  SourceCodeNavigator.GetSourceFragment(_innerContext.SourceCode, stackedTag.Coordinates));
                    }
                }
                catch (XmlParsingException)
                {
                    throw;
                }
                finally
                {
                    _tagStack.Clear();

                    _context      = null;
                    _innerContext = null;
                }
            }
        }
Exemple #10
0
        /// <summary>
        /// Parses HTML content
        /// </summary>
        /// <param name="content">HTML content</param>
        public void Parse(string content)
        {
            int contentLength = content.Length;

            if (contentLength == 0)
            {
                return;
            }

            lock (_parsingSynchronizer)
            {
                _innerContext = new InnerMarkupParsingContext(content);
                _context      = new MarkupParsingContext(_innerContext);

                int endPosition      = contentLength - 1;
                int previousPosition = -1;

                try
                {
                    while (_innerContext.Position <= endPosition)
                    {
                        bool    isProcessed    = false;
                        HtmlTag lastStackedTag = _tagStack.LastOrDefault();

                        // Make sure we're not in a tag, that contains embedded code
                        if (lastStackedTag == null || !lastStackedTag.Flags.IsSet(HtmlTagFlags.EmbeddedCode))
                        {
                            if (_innerContext.PeekCurrentChar() == '<')
                            {
                                switch (_innerContext.PeekNextChar())
                                {
                                case char c when c.IsAlphaNumeric():
                                    // Start tag
                                    isProcessed = ProcessStartTag();

                                    break;

                                case '/':
                                    if (_innerContext.PeekNextChar().IsAlphaNumeric())
                                    {
                                        // End tag
                                        isProcessed = ProcessEndTag();
                                    }
                                    break;

                                case '!':
                                    switch (_innerContext.PeekNextChar())
                                    {
                                    case '-':
                                        if (_innerContext.PeekNextChar() == '-')
                                        {
                                            // Comments
                                            if (_innerContext.PeekNextChar() == '[')
                                            {
                                                // Revealed validating If conditional comments
                                                // (e.g. <!--[if ... ]><!--> or <!--[if ... ]>-->)
                                                isProcessed = ProcessRevealedValidatingIfComment();

                                                if (!isProcessed)
                                                {
                                                    // Hidden If conditional comments (e.g. <!--[if ... ]>)
                                                    isProcessed = ProcessHiddenIfComment();
                                                }
                                            }
                                            else
                                            {
                                                // Revealed validating End If conditional comments
                                                // (e.g. <!--<![endif]-->)
                                                isProcessed = ProcessRevealedValidatingEndIfComment();
                                            }

                                            if (!isProcessed)
                                            {
                                                // HTML comments
                                                isProcessed = ProcessComment();
                                            }
                                        }
                                        break;

                                    case '[':
                                        switch (_innerContext.PeekNextChar())
                                        {
                                        case 'i':
                                        case 'I':
                                            // Revealed If conditional comment (e.g. <![if ... ]>)
                                            isProcessed = ProcessRevealedIfComment();
                                            break;

                                        case 'e':
                                        case 'E':
                                            // Hidden End If conditional comment (e.g. <![endif]-->)
                                            isProcessed = ProcessHiddenEndIfComment();

                                            if (!isProcessed)
                                            {
                                                // Revealed End If conditional comment (e.g. <![endif]>)
                                                isProcessed = ProcessRevealedEndIfComment();
                                            }
                                            break;

                                        case 'C':
                                            // CDATA sections
                                            isProcessed = ProcessCdataSection();
                                            break;
                                        }
                                        break;

                                    case 'D':
                                    case 'd':
                                        // Doctype declaration
                                        isProcessed = ProcessDoctype();
                                        break;
                                    }
                                    break;

                                case '?':
                                    // XML declaration
                                    isProcessed = ProcessXmlDeclaration();
                                    break;
                                }
                            }

                            if (!isProcessed)
                            {
                                // Text
                                ProcessText();
                            }
                        }
                        else
                        {
                            // Embedded code
                            ProcessEmbeddedCode();
                        }

                        if (_innerContext.Position == previousPosition)
                        {
                            throw new MarkupParsingException(
                                      string.Format(Strings.ErrorMessage_MarkupParsingFailed, "HTML"),
                                      _innerContext.NodeCoordinates, _innerContext.GetSourceFragment());
                        }

                        previousPosition = _innerContext.Position;
                    }

                    // Clean up any remaining tags
                    ParseEndTag();

                    // Check whether there were not closed conditional comment
                    if (_conditionalCommentStack.Count > 0)
                    {
                        throw new MarkupParsingException(
                                  Strings.ErrorMessage_NotClosedConditionalComment,
                                  _innerContext.NodeCoordinates, _innerContext.GetSourceFragment());
                    }
                }
                catch (MarkupParsingException)
                {
                    throw;
                }
                finally
                {
                    _tagStack.Clear();
                    _tempAttributes.Clear();
                    _conditionalCommentStack.Clear();
                    _conditionalCommentOpened = false;
                    _xmlTagStack.Clear();
                    _context      = null;
                    _innerContext = null;
                }
            }
        }