示例#1
0
        /// <summary>
        /// End tags handler
        /// </summary>
        /// <param name="context">Markup parsing context</param>
        /// <param name="tagName">Tag name</param>
        private void EndTagHandler(MarkupParsingContext context, string tagName)
        {
            XmlNodeType previousNodeType = _currentNodeType;
            string      previousText     = _currentText;

            _currentNodeType = XmlNodeType.EndTag;
            _currentText     = string.Empty;

            if (_settings.CollapseTagsWithoutContent && previousNodeType == XmlNodeType.StartTag &&
                previousText.Length == 0)
            {
                if (TransformLastStartTagToEmptyTag())
                {
                    FlushBuffer();
                    return;
                }
            }

            if (_settings.MinifyWhitespace && previousNodeType == XmlNodeType.Text &&
                (_endTagBeforeText || _emptyTagBeforeText))
            {
                RemoveLastWhitespaceBufferItems();
            }

            // Add end tag to buffer
            _buffer.Add("</");
            _buffer.Add(tagName);
            _buffer.Add(">");

            FlushBuffer();
        }
示例#2
0
        /// <summary>
        /// Parses a Angular comment directive
        /// </summary>
        /// <param name="commentText">Comment text</param>
        /// <param name="commentDirectiveHandler">Angular comment directive handler</param>
        public static void ParseCommentDirective(string commentText, CommentDirectiveDelegate commentDirectiveHandler)
        {
            Match match = _ngCommentDirectiveRegex.Match(commentText);

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

                GroupCollection groups = match.Groups;

                Group  directiveNameGroup = groups["directiveName"];
                string directiveName      = directiveNameGroup.Value;

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

                    innerContext.IncreasePosition(expressionPosition);
                    commentDirectiveHandler?.Invoke(context, directiveName, expression);
                }
            }
        }
示例#3
0
        /// <summary>
        /// End tags handler
        /// </summary>
        /// <param name="context">Markup parsing context</param>
        /// <param name="tagName">Tag name</param>
        private void EndTagHandler(MarkupParsingContext context, string tagName)
        {
            XmlNodeType previousNodeType = _currentNodeType;
            string      previousText     = _currentText;

            _currentNodeType = XmlNodeType.EndTag;
            _currentText     = string.Empty;

            XmlMinificationOutputWriter output = _output;

            if (_settings.CollapseTagsWithoutContent && previousNodeType == XmlNodeType.StartTag &&
                previousText.Length == 0)
            {
                if (output.TransformLastStartTagToEmptyTag(_settings.RenderEmptyTagsWithSpace))
                {
                    output.Flush();
                    return;
                }
            }

            if (_settings.MinifyWhitespace && previousNodeType == XmlNodeType.Text &&
                (_endTagBeforeText || _emptyTagBeforeText))
            {
                output.RemoveLastWhitespaceItems();
            }

            // Add end tag to buffer
            output.Write("</");
            output.Write(tagName);
            output.Write(">");

            output.Flush();
        }
示例#4
0
        /// <summary>
        /// Parses a Angular class directive
        /// </summary>
        /// <param name="className">Class name</param>
        /// <param name="classDirectiveHandler">Angular class directive handler</param>
        /// <param name="otherContentHandler">Other сontent handler</param>
        public static void ParseClassDirective(string className, ClassDirectiveDelegate classDirectiveHandler,
                                               OtherContentDelegate otherContentHandler)
        {
            int classNameLength = className.Length;
            int currentPosition = 0;
            int remainderLength = classNameLength;

            var innerContext = new InnerMarkupParsingContext(className);
            var context      = new MarkupParsingContext(innerContext);

            Match match = _ngClassDirectiveRegex.Match(className, currentPosition, remainderLength);

            while (match.Success)
            {
                GroupCollection groups = match.Groups;

                Group  directiveNameGroup    = groups["directiveName"];
                int    directiveNamePosition = directiveNameGroup.Index;
                string directiveName         = directiveNameGroup.Value;

                if (directiveNamePosition > currentPosition)
                {
                    string otherContent = className.Substring(currentPosition,
                                                              directiveNamePosition - currentPosition);
                    otherContentHandler?.Invoke(context, otherContent);
                }

                Group  expressionGroup = groups["expression"];
                string expression      = string.Empty;

                if (expressionGroup.Success)
                {
                    int expressionPosition = expressionGroup.Index;
                    expression = expressionGroup.Value.Trim();

                    innerContext.IncreasePosition(expressionPosition - currentPosition);
                    currentPosition = expressionPosition;
                    remainderLength = classNameLength - currentPosition;
                }

                Group semicolonGroup    = groups["semicolon"];
                bool  endsWithSemicolon = semicolonGroup.Success;

                classDirectiveHandler?.Invoke(context, directiveName, expression, endsWithSemicolon);

                int nextItemPosition = match.Index + match.Length;

                innerContext.IncreasePosition(nextItemPosition - currentPosition);
                currentPosition = nextItemPosition;
                remainderLength = classNameLength - currentPosition;

                match = _ngClassDirectiveRegex.Match(className, currentPosition, remainderLength);
            }

            if (remainderLength > 0)
            {
                string otherContent = className.Substring(currentPosition, remainderLength);
                otherContentHandler?.Invoke(context, otherContent);
            }
        }
示例#5
0
        /// <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 match = _ngCommentDirectiveRegex.Match(commentText);

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

                GroupCollection groups = match.Groups;

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

                innerContext.IncreasePosition(directiveNamePosition);
                directiveNameHandler?.Invoke(context, originalDirectiveName, normalizedDirectiveName);

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

                    innerContext.IncreasePosition(expressionPosition - directiveNamePosition);
                    expressionHandler?.Invoke(context, expression);
                }
            }
        }
示例#6
0
        /// <summary>
        /// Start tags handler
        /// </summary>
        /// <param name="context">Markup parsing context</param>
        /// <param name="tagName">Tag name</param>
        /// <param name="attributes">List of attributes</param>
        private void StartTagHandler(MarkupParsingContext context, string tagName,
                                     List <XmlAttribute> attributes)
        {
            XmlNodeType previousNodeType = _currentNodeType;

            _currentNodeType = XmlNodeType.StartTag;
            _currentText     = string.Empty;

            XmlMinificationOutputWriter output = _output;

            if (_settings.MinifyWhitespace && previousNodeType == XmlNodeType.Text &&
                (_startTagBeforeText || _endTagBeforeText || _emptyTagBeforeText ||
                 _ignoredFragmentBeforeText || _xmlDeclarationBeforeText ||
                 _processingInstructionBeforeText || _doctypeBeforeText))
            {
                output.RemoveLastWhitespaceItems();
            }

            output.Flush();

            output.Write("<");
            output.Write(tagName);
            WriteAttributes(attributes);
            output.Write(">");
        }
示例#7
0
        /// <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);
                        }
                    }
                }
            }
        }
示例#8
0
        /// <summary>
        /// CDATA sections handler
        /// </summary>
        /// <param name="context">Markup parsing context</param>
        /// <param name="cdataText">CDATA text</param>
        private void CdataSectionHandler(MarkupParsingContext context, string cdataText)
        {
            _currentNodeType = XmlNodeType.CdataSection;

            _buffer.Add("<![CDATA[");
            _buffer.Add(cdataText);
            _buffer.Add("]]>");
        }
示例#9
0
        /// <summary>
        /// CDATA sections handler
        /// </summary>
        /// <param name="context">Markup parsing context</param>
        /// <param name="cdataText">CDATA text</param>
        private void CdataSectionHandler(MarkupParsingContext context, string cdataText)
        {
            _currentNodeType = XmlNodeType.CdataSection;

            XmlMinificationOutputWriter output = _output;

            output.Write("<![CDATA[");
            output.Write(cdataText);
            output.Write("]]>");
        }
示例#10
0
        /// <summary>
        /// Comments handler
        /// </summary>
        /// <param name="context">Markup parsing context</param>
        /// <param name="commentText">Comment text</param>
        private void CommentHandler(MarkupParsingContext context, string commentText)
        {
            if (!_settings.RemoveXmlComments)
            {
                _currentNodeType = XmlNodeType.Comment;

                _buffer.Add("<!--");
                _buffer.Add(commentText);
                _buffer.Add("-->");
            }
        }
示例#11
0
        /// <summary>
        /// Document type declaration handler
        /// </summary>
        /// <param name="context">Markup parsing context</param>
        /// <param name="doctype">Document type declaration</param>
        private void DoctypeDelegateHandler(MarkupParsingContext context, string doctype)
        {
            _currentNodeType = XmlNodeType.Doctype;

            if (_settings.MinifyWhitespace)
            {
                RemoveLastWhitespaceBufferItems();
            }

            _buffer.Add(Utils.CollapseWhitespace(doctype));
        }
        /// <summary>
        /// Parses a markup of template
        /// </summary>
        /// <param name="content">Markup of template</param>
        /// <param name="templateTagHandler">Template tags delegate</param>
        /// <param name="textHandler">Text delegate</param>
        public static void ParseMarkup(string content,
                                       HtmlParsingHandlers.TemplateTagDelegate templateTagHandler,
                                       HtmlParsingHandlers.TextDelegate textHandler)
        {
            var innerContext = new InnerMarkupParsingContext(content);
            var context      = new MarkupParsingContext(innerContext);

            MatchCollection matches    = _templateTagRegex.Matches(content);
            int             matchCount = matches.Count;

            if (matchCount == 0)
            {
                textHandler?.Invoke(context, content);
                innerContext.IncreasePosition(content.Length);

                return;
            }

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

            for (int matchIndex = 0; matchIndex < matchCount; matchIndex++)
            {
                Match match = matches[matchIndex];
                int   templateTagPosition = match.Index;
                int   templateTagLength   = match.Length;

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

                    textHandler?.Invoke(context, text);
                    innerContext.IncreasePosition(text.Length);
                }

                GroupCollection groups         = match.Groups;
                string          expression     = groups["expression"].Value;
                string          startDelimiter = groups["startDelimiter"].Value;
                string          endDelimiter   = groups["endDelimiter"].Value;

                templateTagHandler?.Invoke(context, expression, startDelimiter, endDelimiter);

                innerContext.IncreasePosition(templateTagLength);
                currentPosition = templateTagPosition + templateTagLength;
            }

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

                innerContext.IncreasePosition(text.Length);
            }
        }
示例#13
0
        /// <summary>
        /// Comments handler
        /// </summary>
        /// <param name="context">Markup parsing context</param>
        /// <param name="commentText">Comment text</param>
        private void CommentHandler(MarkupParsingContext context, string commentText)
        {
            if (!_settings.RemoveXmlComments)
            {
                _currentNodeType = XmlNodeType.Comment;

                XmlMinificationOutputWriter output = _output;
                output.Write("<!--");
                output.Write(commentText);
                output.Write("-->");
            }
        }
示例#14
0
        /// <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 matches    = _ngClassDirectiveRegex.Matches(className);
            int             matchCount = matches.Count;

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

                for (int matchIndex = 0; matchIndex < matchCount; matchIndex++)
                {
                    Match           match  = matches[matchIndex];
                    GroupCollection groups = match.Groups;

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

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

                    directiveNameHandler?.Invoke(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;

                        expressionHandler?.Invoke(context, expression);
                    }

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

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

                        semicolonHandler?.Invoke(context);
                    }
                }
            }
        }
示例#15
0
        /// <summary>
        /// XML declaration handler
        /// </summary>
        /// <param name="context">Markup parsing context</param>
        /// <param name="attributes">List of attributes</param>
        private void XmlDeclarationHandler(MarkupParsingContext context, IList <XmlAttribute> attributes)
        {
            _currentNodeType = XmlNodeType.XmlDeclaration;

            if (_settings.MinifyWhitespace)
            {
                RemoveLastWhitespaceBufferItems();
            }

            _buffer.Add("<?xml");
            RenderAttributes(attributes);
            _buffer.Add("?>");
        }
示例#16
0
        /// <summary>
        /// Ignored fragments handler
        /// </summary>
        /// <param name="context">Markup parsing context</param>
        /// <param name="fragment">Ignored fragment</param>
        private void IgnoredFragmentHandler(MarkupParsingContext context, string fragment)
        {
            _currentNodeType = XmlNodeType.IgnoredFragment;

            if (_settings.MinifyWhitespace)
            {
                RemoveLastWhitespaceBufferItems();
            }

            if (fragment.Length > 0)
            {
                _buffer.Add(fragment);
            }
        }
示例#17
0
        /// <summary>
        /// Document type declaration handler
        /// </summary>
        /// <param name="context">Markup parsing context</param>
        /// <param name="doctype">Document type declaration</param>
        private void DoctypeDelegateHandler(MarkupParsingContext context, string doctype)
        {
            _currentNodeType = XmlNodeType.Doctype;

            XmlMinificationOutputWriter output = _output;

            if (_settings.MinifyWhitespace)
            {
                output.RemoveLastWhitespaceItems();
            }

            output.Write(Utils.CollapseWhitespace(doctype));
            output.Flush();
        }
示例#18
0
        /// <summary>
        /// Processing instruction handler
        /// </summary>
        /// <param name="context">Markup parsing context</param>
        /// <param name="instructionName">Instruction name</param>
        /// <param name="attributes">List of attributes</param>
        private void ProcessingInstructionHandler(MarkupParsingContext context, string instructionName,
                                                  IList <XmlAttribute> attributes)
        {
            _currentNodeType = XmlNodeType.ProcessingInstruction;

            if (_settings.MinifyWhitespace)
            {
                RemoveLastWhitespaceBufferItems();
            }

            _buffer.Add("<?");
            _buffer.Add(instructionName);
            RenderAttributes(attributes);
            _buffer.Add("?>");
        }
示例#19
0
        /// <summary>
        /// XML declaration handler
        /// </summary>
        /// <param name="context">Markup parsing context</param>
        /// <param name="attributes">List of attributes</param>
        private void XmlDeclarationHandler(MarkupParsingContext context, List <XmlAttribute> attributes)
        {
            _currentNodeType = XmlNodeType.XmlDeclaration;

            XmlMinificationOutputWriter output = _output;

            if (_settings.MinifyWhitespace)
            {
                output.RemoveLastWhitespaceItems();
            }

            output.Write("<?xml");
            WriteAttributes(attributes);
            output.Write("?>");

            output.Flush();
        }
示例#20
0
        /// <summary>
        /// Ignored fragments handler
        /// </summary>
        /// <param name="context">Markup parsing context</param>
        /// <param name="fragment">Ignored fragment</param>
        private void IgnoredFragmentHandler(MarkupParsingContext context, string fragment)
        {
            _currentNodeType = XmlNodeType.IgnoredFragment;

            XmlMinificationOutputWriter output = _output;

            if (_settings.MinifyWhitespace)
            {
                output.RemoveLastWhitespaceItems();
            }

            if (fragment.Length > 0)
            {
                output.Write(fragment);
                output.Flush();
            }
        }
示例#21
0
        /// <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 match = _koBeginContainerlessCommentRegex.Match(commentText);

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

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

                innerContext.IncreasePosition(expressionPosition);
                expressionHandler?.Invoke(context, expression);
            }
        }
示例#22
0
        /// <summary>
        /// Empty tags handler
        /// </summary>
        /// <param name="context">Markup parsing context</param>
        /// <param name="tagName">Tag name</param>
        /// <param name="attributes">List of attributes</param>
        private void EmptyTagHandler(MarkupParsingContext context, string tagName,
                                     IList <XmlAttribute> attributes)
        {
            XmlNodeType previousNodeType = _currentNodeType;

            _currentNodeType = XmlNodeType.EmptyTag;
            _currentText     = string.Empty;

            if (_settings.MinifyWhitespace && previousNodeType == XmlNodeType.Text &&
                (_startTagBeforeText || _endTagBeforeText || _emptyTagBeforeText))
            {
                RemoveLastWhitespaceBufferItems();
            }

            _buffer.Add("<");
            _buffer.Add(tagName);
            RenderAttributes(attributes);
            _buffer.Add(_settings.RenderEmptyTagsWithSpace ? " />" : "/>");
        }
示例#23
0
        /// <summary>
        /// Processing instruction handler
        /// </summary>
        /// <param name="context">Markup parsing context</param>
        /// <param name="instructionName">Instruction name</param>
        /// <param name="attributes">List of attributes</param>
        private void ProcessingInstructionHandler(MarkupParsingContext context, string instructionName,
                                                  List <XmlAttribute> attributes)
        {
            _currentNodeType = XmlNodeType.ProcessingInstruction;

            XmlMinificationOutputWriter output = _output;

            if (_settings.MinifyWhitespace)
            {
                output.RemoveLastWhitespaceItems();
            }

            output.Write("<?");
            output.Write(instructionName);
            WriteAttributes(attributes);
            output.Write("?>");

            output.Flush();
        }
示例#24
0
        /// <summary>
        /// Start tags handler
        /// </summary>
        /// <param name="context">Markup parsing context</param>
        /// <param name="tagName">Tag name</param>
        /// <param name="attributes">List of attributes</param>
        private void StartTagHandler(MarkupParsingContext context, string tagName,
                                     IList <XmlAttribute> attributes)
        {
            XmlNodeType previousNodeType = _currentNodeType;

            _currentNodeType = XmlNodeType.StartTag;
            _currentText     = string.Empty;

            if (_settings.MinifyWhitespace && previousNodeType == XmlNodeType.Text &&
                (_startTagBeforeText || _endTagBeforeText || _emptyTagBeforeText ||
                 _xmlDeclarationBeforeText || _processingInstructionBeforeText || _doctypeBeforeText))
            {
                RemoveLastWhitespaceBufferItems();
            }

            _buffer.Add("<");
            _buffer.Add(tagName);
            RenderAttributes(attributes);
            _buffer.Add(">");
        }
示例#25
0
        /// <summary>
        /// Empty tags handler
        /// </summary>
        /// <param name="context">Markup parsing context</param>
        /// <param name="tagName">Tag name</param>
        /// <param name="attributes">List of attributes</param>
        private void EmptyTagHandler(MarkupParsingContext context, string tagName,
                                     List <XmlAttribute> attributes)
        {
            XmlNodeType previousNodeType = _currentNodeType;

            _currentNodeType = XmlNodeType.EmptyTag;
            _currentText     = string.Empty;

            XmlMinificationOutputWriter output = _output;

            if (_settings.MinifyWhitespace && previousNodeType == XmlNodeType.Text &&
                (_startTagBeforeText || _endTagBeforeText || _emptyTagBeforeText))
            {
                output.RemoveLastWhitespaceItems();
            }

            output.Write("<");
            output.Write(tagName);
            WriteAttributes(attributes);
            output.Write(_settings.RenderEmptyTagsWithSpace ? " />" : "/>");

            output.Flush();
        }
示例#26
0
        /// <summary>
        /// Text handler
        /// </summary>
        /// <param name="context">Markup parsing context</param>
        /// <param name="text">Text</param>
        private void TextHandler(MarkupParsingContext context, string text)
        {
            XmlNodeType previousNodeType = _currentNodeType;

            _currentNodeType = XmlNodeType.Text;

            XmlMinificationOutputWriter output = _output;

            if (previousNodeType == XmlNodeType.Text)
            {
                _currentText = text;
                output.Write(text);

                return;
            }

            _xmlDeclarationBeforeText        = false;
            _processingInstructionBeforeText = false;
            _doctypeBeforeText         = false;
            _startTagBeforeText        = false;
            _endTagBeforeText          = false;
            _emptyTagBeforeText        = false;
            _ignoredFragmentBeforeText = false;

            switch (previousNodeType)
            {
            case XmlNodeType.StartTag:
                _startTagBeforeText = true;
                break;

            case XmlNodeType.EndTag:
                _endTagBeforeText = true;
                break;

            case XmlNodeType.EmptyTag:
                _emptyTagBeforeText = true;
                break;

            case XmlNodeType.IgnoredFragment:
                _ignoredFragmentBeforeText = true;
                break;

            case XmlNodeType.XmlDeclaration:
                _xmlDeclarationBeforeText = true;
                break;

            case XmlNodeType.ProcessingInstruction:
                _processingInstructionBeforeText = true;
                break;

            case XmlNodeType.Doctype:
                _doctypeBeforeText = true;
                break;
            }

            if (_settings.MinifyWhitespace)
            {
                if (context.Position == 0)
                {
                    // Processing starting whitespace
                    text = text.TrimStart(null);
                }
                else if (context.Position + text.Length == context.Length)
                {
                    // Processing ending whitespace
                    text = text.TrimEnd(null);
                }
                else if (_xmlDeclarationBeforeText || _processingInstructionBeforeText || _doctypeBeforeText)
                {
                    // Processing whitespace, that followed after
                    // the XML declaration, processing instruction
                    // or document type declaration
                    if (string.IsNullOrWhiteSpace(text))
                    {
                        text = string.Empty;
                    }
                }
            }

            _currentText = text;

            if (text.Length > 0)
            {
                output.Write(text);
            }
        }
示例#27
0
        /// <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);
            }
        }