Exemple #1
0
 /// <summary>
 /// Constructs instance of inner markup parsing context
 /// </summary>
 /// <param name="sourceCode">Source code</param>
 public InnerMarkupParsingContext(string sourceCode)
 {
     _sourceCode       = sourceCode;
     _position         = 0;
     _nodeCoordinates  = new SourceCodeNodeCoordinates(1, 1);
     _peekedCharOffset = 0;
 }
 /// <summary>
 /// Constructs instance of HTML attribute
 /// </summary>
 /// <param name="name">Name</param>
 /// <param name="value">Value</param>
 /// <param name="type">Type</param>
 /// <param name="nameCoordinates">Coordinates of name</param>
 /// <param name="valueCoordinates">Coordinates of value</param>
 public HtmlAttribute(string name, string value, HtmlAttributeType type,
                      SourceCodeNodeCoordinates nameCoordinates, SourceCodeNodeCoordinates valueCoordinates)
 {
     Name             = name;
     Value            = value;
     Type             = type;
     NameCoordinates  = nameCoordinates;
     ValueCoordinates = valueCoordinates;
 }
        /// <summary>
        /// Calculates a absolute node coordinates
        /// </summary>
        /// <param name="baseNodeCoordinates">Base node coordinates</param>
        /// <param name="relativeNodeCoordinates">Relative node coordinates</param>
        /// <returns>Absolute node coordinates</returns>
        public static SourceCodeNodeCoordinates CalculateAbsoluteNodeCoordinates(
			SourceCodeNodeCoordinates baseNodeCoordinates, SourceCodeNodeCoordinates relativeNodeCoordinates)
        {
            int relativeLineNumber = relativeNodeCoordinates.LineNumber;
            int relativeColumnNumber = relativeNodeCoordinates.ColumnNumber;

            int absoluteLineNumber;
            int absoluteColumnNumber;

            if (!baseNodeCoordinates.IsEmpty)
            {
                int baseLineNumber = baseNodeCoordinates.LineNumber;
                int baseColumnNumber = baseNodeCoordinates.ColumnNumber;

                absoluteLineNumber = baseLineNumber;
                absoluteColumnNumber = baseColumnNumber;

                if (relativeLineNumber > 0)
                {
                    if (relativeLineNumber == 1)
                    {
                        if (relativeColumnNumber > 0)
                        {
                            absoluteColumnNumber = baseColumnNumber + relativeColumnNumber - 1;
                        }
                    }
                    else
                    {
                        absoluteLineNumber = baseLineNumber + relativeLineNumber - 1;
                        absoluteColumnNumber = relativeColumnNumber;
                    }
                }
            }
            else
            {
                absoluteLineNumber = relativeLineNumber;
                absoluteColumnNumber = relativeColumnNumber;
            }

            var absoluteNodeCoordinates = new SourceCodeNodeCoordinates(absoluteLineNumber, absoluteColumnNumber);

            return absoluteNodeCoordinates;
        }
Exemple #4
0
        /// <summary>
        /// Increases a current parsing position
        /// </summary>
        /// <param name="increment">Increment</param>
        public void IncreasePosition(int increment)
        {
            int oldPosition = _position;
            int newPosition = oldPosition + increment;

            int fragmentStartPosition = oldPosition;
            int fragmentLength        = increment;

            int lineBreakCount;
            int charRemainderCount;

            SourceCodeNavigator.CalculateLineBreakCount(_sourceCode, fragmentStartPosition, fragmentLength,
                                                        out lineBreakCount, out charRemainderCount);
            SourceCodeNodeCoordinates currentNodeCoordinates = _nodeCoordinates;

            _nodeCoordinates = SourceCodeNavigator.CalculateAbsoluteNodeCoordinates(currentNodeCoordinates,
                                                                                    lineBreakCount, charRemainderCount);
            _position = newPosition;
        }
        /// <summary>
        /// Calculates a absolute node coordinates
        /// </summary>
        /// <param name="baseNodeCoordinates">Base node coordinates</param>
        /// <param name="additionalContent">Additional content</param>
        /// <returns>Absolute node coordinates</returns>
        public static SourceCodeNodeCoordinates CalculateAbsoluteNodeCoordinates(
			SourceCodeNodeCoordinates baseNodeCoordinates, string additionalContent)
        {
            int lineBreakCount = 0;
            int charRemainderCount = 0;

            if (!string.IsNullOrEmpty(additionalContent))
            {
                CalculateLineBreakCount(additionalContent, out lineBreakCount, out charRemainderCount);
            }

            int absoluteLineNumber;
            int absoluteColumnNumber;

            if (!baseNodeCoordinates.IsEmpty)
            {
                int baseLineNumber = baseNodeCoordinates.LineNumber;
                int baseColumnNumber = baseNodeCoordinates.ColumnNumber;

                if (lineBreakCount > 0)
                {
                    absoluteLineNumber = baseLineNumber + lineBreakCount;
                    absoluteColumnNumber = charRemainderCount + 1;
                }
                else
                {
                    absoluteLineNumber = baseLineNumber;
                    absoluteColumnNumber = baseColumnNumber + charRemainderCount;
                }
            }
            else
            {
                absoluteLineNumber = lineBreakCount + 1;
                absoluteColumnNumber = charRemainderCount + 1;
            }

            var absoluteNodeCoordinates = new SourceCodeNodeCoordinates(absoluteLineNumber, absoluteColumnNumber);

            return absoluteNodeCoordinates;
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="XmlParsingException"/> class
 /// with a specified error message, node coordinates, source fragment
 /// and reference to the inner exception that is the cause of this exception
 /// </summary>
 /// <param name="message">Error message that explains the reason for the exception</param>
 /// <param name="nodeCoordinates">Node coordinates</param>
 /// <param name="sourceFragment">Source fragment</param>
 /// <param name="innerException">Exception that is the cause of the current exception</param>
 public XmlParsingException(string message, SourceCodeNodeCoordinates nodeCoordinates,
                            string sourceFragment, Exception innerException)
     : base(message, nodeCoordinates, sourceFragment, innerException)
 {
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="CodeProcessingException"/> class
 /// with a specified error message, node coordinates and source fragment
 /// </summary>
 /// <param name="message">Error message that explains the reason for the exception</param>
 /// <param name="nodeCoordinates">Node coordinates</param>
 /// <param name="sourceFragment">Source fragment</param>
 protected CodeProcessingException(string message, SourceCodeNodeCoordinates nodeCoordinates, string sourceFragment)
     : this(message, nodeCoordinates, sourceFragment, null)
 {
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="CodeProcessingException"/> class
 /// with a specified error message, node coordinates, source fragment
 /// and reference to the inner exception that is the cause of this exception
 /// </summary>
 /// <param name="message">Error message that explains the reason for the exception</param>
 /// <param name="nodeCoordinates">Node coordinates</param>
 /// <param name="sourceFragment">Source fragment</param>
 /// <param name="innerException">Exception that is the cause of the current exception</param>
 protected CodeProcessingException(string message, SourceCodeNodeCoordinates nodeCoordinates,
                                   string sourceFragment, Exception innerException)
     : this(message, nodeCoordinates.LineNumber, nodeCoordinates.ColumnNumber,
            sourceFragment, innerException)
 {
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="MarkupParsingException"/> class
 /// with a specified error message, node coordinates and source fragment
 /// </summary>
 /// <param name="message">Error message that explains the reason for the exception</param>
 /// <param name="nodeCoordinates">Node coordinates</param>
 /// <param name="sourceFragment">Source fragment</param>
 public MarkupParsingException(string message, SourceCodeNodeCoordinates nodeCoordinates, string sourceFragment)
     : base(message, nodeCoordinates, sourceFragment)
 {
 }
Exemple #10
0
 /// <summary>
 /// Constructs instance of stacked XML tag
 /// </summary>
 /// <param name="name">Name</param>
 /// <param name="coordinates">Coordinates of tag</param>
 public StackedXmlTag(string name, SourceCodeNodeCoordinates coordinates)
 {
     Name        = name;
     Coordinates = coordinates;
 }
Exemple #11
0
        /// <summary>
        /// Process a attributes
        /// </summary>
        /// <returns>List of attributes</returns>
        private List <HtmlAttribute> ProcessAttributes()
        {
            string content         = _innerContext.SourceCode;
            int    currentPosition = _innerContext.Position;
            SourceCodeNodeCoordinates currentCoordinates = _innerContext.NodeCoordinates;

            Match match = _attributeRegex.Match(content, currentPosition, _innerContext.RemainderLength);

            while (match.Success)
            {
                GroupCollection groups                  = match.Groups;
                Group           attributeNameGroup      = groups["attributeName"];
                Group           attributeEqualSignGroup = groups["attributeEqualSign"];
                Group           attributeValueGroup     = groups["attributeValue"];

                string attributeName            = attributeNameGroup.Value;
                string attributeNameInLowercase = attributeName;
                if (Utils.ContainsUppercaseCharacters(attributeName))
                {
                    attributeNameInLowercase = attributeName.ToLowerInvariant();
                }
                string attributeValue = null;

                if (attributeEqualSignGroup.Success)
                {
                    if (attributeValueGroup.Success)
                    {
                        attributeValue = attributeValueGroup.Value;
                        if (!string.IsNullOrWhiteSpace(attributeValue))
                        {
                            attributeValue = HtmlAttributeValueHelpers.Decode(attributeValue);
                        }
                    }
                    else
                    {
                        attributeValue = string.Empty;
                    }
                }

                var attributeNameCoordinates = SourceCodeNodeCoordinates.Empty;
                int attributeNamePosition    = -1;
                if (attributeNameGroup.Success)
                {
                    attributeNamePosition = attributeNameGroup.Index;
                }

                if (attributeNamePosition != -1)
                {
                    int lineBreakCount;
                    int charRemainderCount;

                    SourceCodeNavigator.CalculateLineBreakCount(content, currentPosition,
                                                                attributeNamePosition - currentPosition, out lineBreakCount, out charRemainderCount);
                    attributeNameCoordinates = SourceCodeNavigator.CalculateAbsoluteNodeCoordinates(
                        currentCoordinates, lineBreakCount, charRemainderCount);

                    currentPosition    = attributeNamePosition;
                    currentCoordinates = attributeNameCoordinates;
                }

                var attributeValueCoordinates = SourceCodeNodeCoordinates.Empty;
                int attributeValuePosition    = -1;
                if (attributeValueGroup.Success)
                {
                    attributeValuePosition = attributeValueGroup.Index;
                }

                if (attributeValuePosition != -1)
                {
                    int lineBreakCount;
                    int charRemainderCount;

                    SourceCodeNavigator.CalculateLineBreakCount(content, currentPosition,
                                                                attributeValuePosition - currentPosition, out lineBreakCount, out charRemainderCount);
                    attributeValueCoordinates = SourceCodeNavigator.CalculateAbsoluteNodeCoordinates(
                        currentCoordinates, lineBreakCount, charRemainderCount);

                    currentPosition    = attributeValuePosition;
                    currentCoordinates = attributeValueCoordinates;
                }

                var attribute = new HtmlAttribute(attributeName, attributeNameInLowercase, attributeValue,
                                                  HtmlAttributeType.Unknown, attributeNameCoordinates, attributeValueCoordinates);
                _tempAttributes.Add(attribute);

                _innerContext.IncreasePosition(match.Length);
                match = _attributeRegex.Match(content, _innerContext.Position, _innerContext.RemainderLength);
            }

            int attributeCount = _tempAttributes.Count;
            var attributes     = new List <HtmlAttribute>(attributeCount);

            for (int attributeIndex = 0; attributeIndex < attributeCount; attributeIndex++)
            {
                attributes.Add(_tempAttributes[attributeIndex]);
            }

            _tempAttributes.Clear();

            return(attributes);
        }
        /// <summary>
        /// Formats a line of source code
        /// </summary>
        /// <param name="line">Line content</param>
        /// <param name="nodeCoordinates">Node coordinates</param>
        /// <param name="lineNumberSize">Number of symbols in the line number caption</param>
        /// <param name="fragmentStartPosition">Start position of source fragment</param>
        /// <param name="fragmentLength">Length of source fragment</param>
        /// <param name="tabSize">Number of spaces in the tab</param>
        /// <returns>Formatted line</returns>
        private static string FormatSourceCodeLine(string line, SourceCodeNodeCoordinates nodeCoordinates,
			int lineNumberSize, int fragmentStartPosition = 0, int fragmentLength = 0, byte tabSize = 4)
        {
            const string ellipsisSymbol = "…";
            const byte leftPaddingSize = 7;

            int lineNumber = nodeCoordinates.LineNumber;
            int columnNumber = nodeCoordinates.ColumnNumber;
            int lineLength = line.Length;

            string processedLine;
            if ((fragmentStartPosition == 0 && fragmentLength == lineLength))
            {
                processedLine = line;
            }
            else if (fragmentStartPosition >= lineLength)
            {
                processedLine = string.Empty;
            }
            else
            {
                int fragmentEndPosition = fragmentStartPosition + fragmentLength - 1;

                bool beginningCutOff = (fragmentStartPosition > 0);
                bool endingCutOff = (fragmentEndPosition <= lineLength);
                if (fragmentEndPosition + 1 == lineLength)
                {
                    endingCutOff = false;
                }

                if (fragmentEndPosition >= lineLength)
                {
                    endingCutOff = false;
                    fragmentEndPosition = lineLength - 1;
                    fragmentLength = fragmentEndPosition - fragmentStartPosition + 1;
                }

                processedLine = line.Substring(fragmentStartPosition, fragmentLength);
                if (beginningCutOff)
                {
                    processedLine = ellipsisSymbol + processedLine;
                }
                if (endingCutOff)
                {
                    processedLine = processedLine + ellipsisSymbol;
                }
            }

            string result = string.Format("Line {0}: {1}",
                lineNumber.ToString(CultureInfo.InvariantCulture).PadLeft(lineNumberSize),
                processedLine.TabsToSpaces(tabSize));
            if (columnNumber > 0)
            {
                int cursorOffset = columnNumber - fragmentStartPosition;
                if (fragmentStartPosition > 0)
                {
                    cursorOffset++;
                }

                result += Environment.NewLine + string.Empty
                    .PadRight(processedLine.Substring(0, cursorOffset - 1)
                    .TabsToSpaces(tabSize).Length + lineNumberSize + leftPaddingSize)
                    .Replace(" ", "-") + "^"
                    ;
            }

            return result;
        }
        /// <summary>
        /// Gets a source fragment
        /// </summary>
        /// <param name="sourceCode">Source code</param>
        /// <param name="nodeCoordinates">Node coordinates</param>
        /// <param name="tabSize">Number of spaces in the tab</param>
        /// <param name="maxFragmentLength">Maximum length of the source fragment</param>
        /// <returns>Source fragment</returns>
        public static string GetSourceFragment(string sourceCode,
			SourceCodeNodeCoordinates nodeCoordinates, byte tabSize = DEFAULT_TAB_SIZE,
			int maxFragmentLength = DEFAULT_MAX_FRAGMENT_LENGTH)
        {
            string sourceFragment = string.Empty;
            int lineNumber = nodeCoordinates.LineNumber;
            int columnNumber = nodeCoordinates.ColumnNumber;

            if (!string.IsNullOrEmpty(sourceCode))
            {
                int previousLineNumber = lineNumber - 1;
                int currentLineNumber = lineNumber;
                int nextLineNumber = lineNumber + 1;

                string previousLine = string.Empty;
                string currentLine = string.Empty;
                string nextLine = string.Empty;

                int lineCount = 0;
                int lineBreakPosition = int.MinValue;
                int lineBreakLength = 0;

                do
                {
                    string line;
                    int startLinePosition = (lineBreakPosition == int.MinValue) ? 0 : lineBreakPosition + lineBreakLength;

                    FindNextLineBreak(sourceCode, startLinePosition, out lineBreakPosition, out lineBreakLength);

                    if (lineBreakPosition != -1)
                    {
                        line = sourceCode.Substring(startLinePosition, lineBreakPosition - startLinePosition);
                    }
                    else
                    {
                        line = sourceCode.Substring(startLinePosition);
                    }

                    lineCount++;

                    if (lineCount == previousLineNumber)
                    {
                        previousLine = line;
                    }
                    else if (lineCount == currentLineNumber)
                    {
                        currentLine = line;
                    }
                    else if (lineCount == nextLineNumber)
                    {
                        nextLine = line;
                    }
                }
                while (lineBreakPosition != -1 && lineCount <= nextLineNumber);

                int lineNumberSize = (nextLineNumber).ToString(CultureInfo.InvariantCulture).Length;
                if (currentLineNumber == lineCount)
                {
                    lineNumberSize = currentLineNumber.ToString(CultureInfo.InvariantCulture).Length;
                }

                int fragmentStartPosition;
                int fragmentLength;

                CalculateCutPositions(currentLine, columnNumber, maxFragmentLength,
                    out fragmentStartPosition, out fragmentLength);

                var sourceFragmentBuilder = new StringBuilder();

                if (currentLine.Length > 0)
                {
                    if (previousLine.Length > 0)
                    {
                        sourceFragmentBuilder.AppendLine(FormatSourceCodeLine(previousLine,
                            new SourceCodeNodeCoordinates(previousLineNumber, 0),
                            lineNumberSize, fragmentStartPosition, fragmentLength, tabSize));
                    }

                    sourceFragmentBuilder.AppendLine(FormatSourceCodeLine(currentLine,
                        new SourceCodeNodeCoordinates(currentLineNumber, columnNumber),
                        lineNumberSize, fragmentStartPosition, fragmentLength, tabSize));

                    if (nextLine.Length > 0)
                    {
                        sourceFragmentBuilder.AppendLine(FormatSourceCodeLine(nextLine,
                            new SourceCodeNodeCoordinates(nextLineNumber, 0),
                            lineNumberSize, fragmentStartPosition, fragmentLength, tabSize));
                    }
                }

                sourceFragment = sourceFragmentBuilder.ToString();
            }

            return sourceFragment;
        }
        /// <summary>
        /// Calculates a node coordinates
        /// </summary>
        /// <param name="sourceCode">Source code</param>
        /// <param name="nodePosition">Current node position</param>
        /// <returns>Node coordinates</returns>
        public static SourceCodeNodeCoordinates CalculateNodeCoordinates(string sourceCode, int nodePosition)
        {
            if (string.IsNullOrEmpty(sourceCode) || nodePosition >= sourceCode.Length)
            {
                return SourceCodeNodeCoordinates.Empty;
            }

            int fragmentLength = nodePosition + 1;
            int lineBreakCount;
            int charRemainderCount;

            CalculateLineBreakCount(sourceCode, 0, fragmentLength,
                out lineBreakCount, out charRemainderCount);

            var nodeCoordinates = new SourceCodeNodeCoordinates(lineBreakCount + 1, charRemainderCount + 1);

            return nodeCoordinates;
        }
        /// <summary>
        /// Calculates a absolute node coordinates
        /// </summary>
        /// <param name="baseNodeCoordinates">Base node coordinates</param>
        /// <param name="lineBreakCount">Number of line breaks</param>
        /// <param name="charRemainderCount">Number of characters left</param>
        /// <returns>Absolute node coordinates</returns>
        public static SourceCodeNodeCoordinates CalculateAbsoluteNodeCoordinates(
			SourceCodeNodeCoordinates baseNodeCoordinates, int lineBreakCount, int charRemainderCount)
        {
            int absoluteLineNumber;
            int absoluteColumnNumber;

            if (!baseNodeCoordinates.IsEmpty)
            {
                int baseLineNumber = baseNodeCoordinates.LineNumber;
                int baseColumnNumber = baseNodeCoordinates.ColumnNumber;

                if (lineBreakCount > 0)
                {
                    absoluteLineNumber = baseLineNumber + lineBreakCount;
                    absoluteColumnNumber = charRemainderCount + 1;
                }
                else
                {
                    absoluteLineNumber = baseLineNumber;
                    absoluteColumnNumber = baseColumnNumber + charRemainderCount;
                }
            }
            else
            {
                absoluteLineNumber = lineBreakCount + 1;
                absoluteColumnNumber = charRemainderCount + 1;
            }

            var absoluteNodeCoordinates = new SourceCodeNodeCoordinates(absoluteLineNumber, absoluteColumnNumber);

            return absoluteNodeCoordinates;
        }