示例#1
0
        /**
         * Prepares the given string s for presentation on an html
         * page.
         *
         * Html encodes the special characters as follows:
         *
         *      single quote:   "'"
         *      double quote:   """
         *      less than:      "<"
         *      greater than:   ">"
         *      ampersand:      "&"
         *
         * Replaces tabs by blanks relative to the given tabsize.
         *   Default: tabsize = 4
         *
         * Prefaces each line with a line number if desired.
         *   Default: showlinenumbers = false
         *
         * Line numbers displayed start at 1 to follow the pattern
         * used in Visual Studio.
         *
         * Will return the original string s if s does not need any
         * of the following transformations:
         *   html encoding
         *   tabs to blanks
         *   line numbering
         *
         * If any transformations take place then the return string
         * normalizes the line breaks to '\n'.
         *
         * The result of this method should be displayed using
         * preformatted text, that is, via a pre-tag or via the css
         * setting white-space:pre.
         */
        public static string TextToHtml
            (string s, int tabsize = 4, bool showlinenumbers = false)
        {
            if (IsTrivial(s))
            {
                return(s);
            }

            bool replaceHtml = hasHtmlSpecialRegex.IsMatch(s);

            bool replaceTabs = (tabsize > 0) && (hasTabRegex.IsMatch(s));

            bool needsWork = replaceHtml || replaceTabs || showlinenumbers;

            if (!needsWork)
            {
                return(s);
            }

            StringBuilder builder = new StringBuilder();

            int length = s.Length;

            List <Range> linerangelist = StringTools.LineRangeList(s);

            int linecount = linerangelist.Count;
            int lineindex = 0;

            while (lineindex < linecount)
            {
                // process the line at the lineindex
                Range linerange = linerangelist[lineindex];

                int start = linerange.start;
                int limit = linerange.limit;

                // increment lineindex here
                // since visible line numbers start at 1

                lineindex++;

                // if showlinenumbers is true, add the line number

                if (showlinenumbers)
                {
                    builder.Append(lineindex.ToString("000000  "));
                }

                // index is the character position in the string
                int index = start;

                // position is the character position on the line
                // after any earlier replacement of tabs by blanks
                //
                // characters used for the line number are ignored
                int position = 0;

                while (index < limit)
                {
                    char c = s[index];

                    if (c == '\t')
                    {
                        if (tabsize > 0)
                        {
                            int spaces = tabsize - (position % tabsize);

                            for (int i = 0; i < spaces; i++)
                            {
                                builder.Append(' ');
                            }

                            position += spaces;
                        }
                        else
                        {
                            builder.Append(c);

                            position++;
                        }
                    }
                    else
                    {
                        if (isHtmlSpecial(c))
                        {
                            builder.Append(HtmlEncode(c));
                        }
                        else
                        {
                            builder.Append(c);
                        }

                        position++;
                    }

                    index++;
                }

                if (limit < length)
                {
                    builder.Append('\n');
                }
            }

            return(builder.ToString());
        }
示例#2
0
        /**
         * Prepares the given string s for presentation on an html
         * page.
         *
         * Enhances the method TextToHtml by permitting ranges of
         * the text to be highlighted.  Each range is placed in a
         * span-tag with css class 'highlight'.  Thus, the nature
         * of the highlighting is controlled by the css on the
         * page.
         *
         * Html encodes the special characters as follows:
         *
         *      single quote:   "&apos;"
         *      double quote:   "&quot;"
         *      less than:      "&lt;"
         *      greater than:   "&gt;"
         *      ampersand:      "&amp;"
         *
         * Replaces tabs by blanks relative to the given tabsize.
         *   Default: tabsize = 4
         *
         * Prefaces each line with a line number if desired.
         *   Default: showlinenumbers = true
         *
         * Permits the caller to decide whether to show all lines or
         * to show only the lines with highlights.
         *   Default: showall = false
         *
         * The reason for these defaults is that this method is used
         * to show the results of a search.  In this situation, the
         * user is most interested in seeing the lines that contain
         * search results and not all other lines.  By setting
         *   showlinenumbers = true
         *   showall = false
         * the lines that contain search results are identified and
         * no other lines are displayed.
         *
         * Line numbers displayed start at 1 to follow the pattern
         * used in Visual Studio.
         *
         * There is an interesting edge case if no ranges are given
         * to be highlighted.  In that case:
         *
         *   If showall=false, there is nothing to show and this
         *   method returns an empty string.
         *
         *   If showall=true, this method simply calls TextToHtml.
         *
         * If any transformations take place then the return string
         * normalizes the line breaks to '\n'.
         *
         * The result of this method should be displayed using
         * preformatted text, that is, via a pre-tag or via the css
         * setting white-space:pre.
         */
        public static string HighlightMarkup
            (string s,
            List <Range> highlightlist,
            int tabsize          = 4,
            bool showlinenumbers = true,
            bool showall         = false)
        {
            if (IsTrivial(s))
            {
                return(s);
            }

            if (IsTrivial(highlightlist))
            {
                if (showall)
                {
                    return(TextToHtml(s, tabsize, showlinenumbers));
                }
                else
                {
                    return("");
                }
            }

            StringBuilder builder = new StringBuilder();

            int length = s.Length;

            // Set up for line processing

            List <Range> linerangelist = StringTools.LineRangeList(s);

            int linecount = linerangelist.Count;
            int lineindex = 0;

            // Set up for highlight processing

            int highcount = highlightlist.Count;
            int highindex = 0;

            // data for dealing with the highlight overlap range list
            // for hightlight ranges than intersect a line range

            // overlap: the list of highlight range overlaps
            // overlapcount = overlap.Count

            // next: next highlight overlap range to process
            // nextrange = overlap[next]

            // open: nextrange.start
            // shut: nextrange.limit

            List <Range> overlap      = null;
            int          overlapcount = 0;

            int   next = 0;
            Range nextrange;

            int open = -1;
            int shut = -1;


            while (lineindex < linecount)
            {
                // process the line at the lineindex
                Range linerange = linerangelist[lineindex];

                int start = linerange.start;
                int limit = linerange.limit;

                // increment lineindex here
                // since visible line numbers start at 1
                //
                // this guarantees that lineindex is updated
                // if this line will be skipped later because
                // it has no highlights

                lineindex++;


                // construct the overlap highlight ranges that
                // intersect this line range, if any

                overlap      = null;
                overlapcount = 0;

                if (highindex < highcount)
                {
                    while ((highindex < highcount) &&
                           (highlightlist[highindex].limit < start))
                    {
                        highindex++;
                    }

                    while ((highindex < highcount) &&
                           (highlightlist[highindex].start < limit))
                    {
                        Range?r = Range.Intersect(linerange, highlightlist[highindex]);

                        if (r.HasValue)
                        {
                            Range rv = r.Value;

                            if (rv.length > 0)
                            {
                                if (overlap == null)
                                {
                                    overlap = new List <Range>();
                                }

                                overlap.Add(rv);
                            }

                            if (highlightlist[highindex].limit <= limit)
                            {
                                highindex++;
                            }
                            else
                            {
                                break;
                            }
                        }
                        else
                        {
                            break;
                        }
                    }
                }

                if (overlap != null)
                {
                    overlapcount = overlap.Count;
                }

                // skip this line if
                //   showall is false
                // and
                //   there is no highlight to do

                if ((!showall) && (overlapcount == 0))
                {
                    continue;
                }


                // if showlinenumbers is true, add the line number
                // at this stage of the processing

                if (showlinenumbers)
                {
                    builder.Append(lineindex.ToString("000000  "));
                }


                // index is the character position in the string
                int index = start;

                // position is the character position on the line
                // after any earlier replacement of tabs by blanks
                //
                // characters used for the line number are ignored
                int position = 0;


                // get set to process highlights
                next = 0;

                if (next < overlapcount)
                {
                    nextrange = overlap[next];
                    open      = nextrange.start;
                    shut      = nextrange.limit;
                }
                else
                {
                    open = -1;
                    shut = -1;
                }


                while (index < limit)
                {
                    // step 1: deal with highlight at this index

                    if (index == shut)
                    {
                        builder.Append(highlightshut);

                        next++;

                        if (next < overlapcount)
                        {
                            nextrange = overlap[next];
                            open      = nextrange.start;
                            shut      = nextrange.limit;
                        }
                        else
                        {
                            open = -1;
                            shut = -1;
                        }
                    }

                    if (index == open)
                    {
                        builder.Append(highlightopen);
                    }

                    // step 2: deal with character at this index

                    char c = s[index];

                    if (c == '\t')
                    {
                        if (tabsize > 0)
                        {
                            int spaces = tabsize - (position % tabsize);

                            for (int i = 0; i < spaces; i++)
                            {
                                builder.Append(' ');
                            }

                            position += spaces;
                        }
                        else
                        {
                            builder.Append(c);

                            position++;
                        }
                    }
                    else
                    {
                        if (isHtmlSpecial(c))
                        {
                            builder.Append(HtmlEncode(c));
                        }
                        else
                        {
                            builder.Append(c);
                        }

                        position++;
                    }

                    index++;
                }

                if (limit == shut)
                {
                    builder.Append(highlightshut);
                }

                if (limit < length)
                {
                    builder.Append('\n');
                }
            }

            return(builder.ToString());
        }
示例#3
0
        /*
         * Returns a string with the tabs in s converted to blanks
         * based on the given tabsize.
         *
         * If omitted, tabsize defaults to 4.
         *
         * Returns the original string if:
         *   s is trivial
         *   s does not contain a tab character
         *   The given tabsize is less than or equal to 0
         *
         * This method simply converts tabs and does no other task.
         *
         * If tabs are converted then the return string normalizes
         * the line breaks to '\n'.
         */
        public static string TabsToBlanks
            (string s, int tabsize = 4)
        {
            if (IsTrivial(s))
            {
                return(s);
            }

            if (tabsize <= 0)
            {
                return(s);
            }

            if (!hasTabRegex.IsMatch(s))
            {
                return(s);
            }

            StringBuilder builder = new StringBuilder();

            int length = s.Length;

            List <Range> linerangelist = StringTools.LineRangeList(s);

            int linecount = linerangelist.Count;
            int lineindex = 0;

            while (lineindex < linecount)
            {
                // process the line at the lineindex
                Range linerange = linerangelist[lineindex];

                int start = linerange.start;
                int limit = linerange.limit;

                // increment lineindex here
                lineindex++;

                // index is the character position in the string
                int index = start;

                // position is the character position on the line
                // after any earlier replacement of tabs by blanks
                int position = 0;

                while (index < limit)
                {
                    char c = s[index];

                    if (c == '\t')
                    {
                        int spaces = tabsize - (position % tabsize);

                        for (int i = 0; i < spaces; i++)
                        {
                            builder.Append(' ');
                        }

                        position += spaces;
                    }
                    else
                    {
                        builder.Append(c);

                        position++;
                    }

                    index++;
                }

                if (limit < length)
                {
                    builder.Append('\n');
                }
            }

            return(builder.ToString());
        }