Beispiel #1
0
        /// <summary>
        ///   Parses the given document to find all tags between the beginning of the document and the specified
        ///   end line.
        /// </summary>
        /// <remarks>
        ///   The <paramref name="p_pctCompleteTagCallback" /> is called whenever a complete tag has been parsed.
        ///   A complete tag is a tag whose opening and closing tags have been found (for example, &lt;b>..&lt/b>).
        ///   The stack that is returned contains all the unclosed tags found, and so represents where in the
        ///   document heirarchy the line falls.
        /// </remarks>
        /// <param name="p_docDocument">The document to parse.</param>
        /// <param name="p_intEndLine">The line of the document at which to stop parsing.</param>
        /// <param name="p_pctCompleteTagCallback">The method to call whenever a complete tag is parsed.</param>
        /// <returns>A stack containing all the unclosed tags found.</returns>
        /// <exception cref="ArgumentOutOfRangeException">
        ///   Thrown if <paramref name="p_intEndLine" /> is greater than
        ///   or equal to the <see cref="IDocument.TotalNumberOfLines" /> of <paramref name="p_docDocument" />.
        /// </exception>
        public static TagStack ParseTags(IDocument p_docDocument, Int32 p_intEndLine, ParsedTag p_pctCompleteTagCallback,
                                         ParsedTag p_pctUnclosedTagCallback)
        {
            if (p_intEndLine >= p_docDocument.TotalNumberOfLines)
            {
                throw new ArgumentOutOfRangeException("p_intEndLine", p_intEndLine,
                                                      "The given end line paramater is outside of the range of lines in the given document.");
            }
            //parse the buffer
            var stkTags = new TagStack();

            for (var i = 0; i <= p_intEndLine; i++)
            {
                var strLine        = p_docDocument.GetText(p_docDocument.GetLineSegment(i));
                var intLineNum     = i;
                var intLastOpenPos = strLine.LastIndexOf('<');
                if (intLastOpenPos < 0)
                {
                    continue;
                }
                var intLastClosePos = strLine.LastIndexOf('>');
                if ((intLastClosePos > -1) && (intLastOpenPos > intLastClosePos))
                {
                    var stbLines = new StringBuilder(strLine);
                    //there is an open tag on this line - read lines until it is closed.
                    for (; i <= p_intEndLine; i++)
                    {
                        var strNextLine = p_docDocument.GetText(p_docDocument.GetLineSegment(i));
                        intLastClosePos = strLine.LastIndexOf('>');
                        stbLines.Append(strNextLine);
                        if (intLastClosePos < 0)
                        {
                            i--;
                            break;
                        }
                    }
                    strLine = stbLines.ToString();
                }

                var mclLineTags = rgxTagContents.Matches(strLine);
                foreach (Match mtcTag in mclLineTags)
                {
                    var strTag     = mtcTag.Groups[1].Value.Trim();
                    var strTagName = rgxTagName.Match(strTag).Groups[1].Value;
                    if (strTag.StartsWith("/"))
                    {
                        if (stkTags.Contains(strTagName))
                        {
                            while (!stkTags.Peek().Equals(strTagName))
                            {
                                var tpsTag   = stkTags.Pop();
                                var tlcStart = new TextLocation(tpsTag.Column, tpsTag.LineNumber);
                                var tlcEnd   = new TextLocation(tpsTag.Column + tpsTag.Name.Length, tpsTag.LineNumber);
                                if (p_pctUnclosedTagCallback != null)
                                {
                                    p_pctUnclosedTagCallback(p_docDocument, tpsTag.Name, tlcStart, tlcEnd);
                                }
                            }
                            var tpsCompleteTag = stkTags.Pop();
                            if (p_pctCompleteTagCallback != null)
                            {
                                var tlcStart      = new TextLocation(tpsCompleteTag.Column, tpsCompleteTag.LineNumber);
                                var intEndFoldPos = mtcTag.Groups[1].Index;
                                var tlcEnd        = new TextLocation(intEndFoldPos, intLineNum);
                                p_pctCompleteTagCallback(p_docDocument, strTagName, tlcStart, tlcEnd);
                            }
                        }
                    }
                    else
                    {
                        if (!strTag.EndsWith("/"))
                        {
                            stkTags.Push(strTagName, intLineNum, mtcTag.Groups[1].Index);
                        }
                    }
                }
            }
            return(stkTags);
        }