跨度插入逻辑帮助

发布于 2024-08-21 23:33:01 字数 1198 浏览 4 评论 0原文

我有这样的文本

"You are advised to grant access to these settings only if you are sure you want to allow this program to run automatically when your computer starts. Otherwise it is better to deny access."

,我有 3 个选择,

1. StartIndex = 8, Length = 16  // "advised to grant" 
2. StartIndex = 16, Length = 33  //"to grant access to these settings"
3. StartIndex = 35, Length = 26 // "these settings only if you"

我需要插入跨度标签并突出显示选择,单词的交叉点应该以不同的颜色突出显示,

结果应该是这样的,

"You are <span style= 'background-color:#F9DA00'>advised </span> <span id = 'intersection' style= 'background-color:#F9DA00'>to grant </span> <span style= 'background-color:#F9DA00'>advised </span> <span style= 'background-color:#F9DA00'>access to </span>
<span id = 'intersection' style= 'background-color:#F9DA00'>these settings</span>
<span style= 'background-color:#F9DA00'>only if you </span>  sure you want to allow this program to run automatically when your computer starts. Otherwise it is better to deny access."

请帮我解决这个问题,我一直在尝试找出一个逻辑很长时间了,但到目前为止还没有运气

I have a text like this

"You are advised to grant access to these settings only if you are sure you want to allow this program to run automatically when your computer starts. Otherwise it is better to deny access."

and i have 3 selections,

1. StartIndex = 8, Length = 16  // "advised to grant" 
2. StartIndex = 16, Length = 33  //"to grant access to these settings"
3. StartIndex = 35, Length = 26 // "these settings only if you"

i need to insert span tags and highlight selections, and intersections of words should be highlighted in different color,

result should be something like this

"You are <span style= 'background-color:#F9DA00'>advised </span> <span id = 'intersection' style= 'background-color:#F9DA00'>to grant </span> <span style= 'background-color:#F9DA00'>advised </span> <span style= 'background-color:#F9DA00'>access to </span>
<span id = 'intersection' style= 'background-color:#F9DA00'>these settings</span>
<span style= 'background-color:#F9DA00'>only if you </span>  sure you want to allow this program to run automatically when your computer starts. Otherwise it is better to deny access."

please help me to sort this out, i have been trying to figure-out a logic for a long time now and no luck so far

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

情何以堪。 2024-08-28 23:33:01

标记注释:ID 需要唯一。让它们成为类:class="intersection"

Markup comment: IDs need to be unique. Make them classes instead: class="intersection".

还不是爱你 2024-08-28 23:33:01

最终我自己找到了解决方案,希望这对将来的人也有帮助

 public enum SortDirection
    {
        Ascending, Descending
    }

    public enum SpanType
    {
        Intersection, InnerSpan, Undefined
    }

    class Program
    {
        static void Main(string[] args)
        {
            string MessageText = @"You are advised to grant access to these settings only if you are sure you want to allow this program to run automatically when your computer starts. Otherwise it is better to deny access.";

            List<Span> spanList = new List<Span>();
            List<Span> intersectionSpanList = new List<Span>();

            spanList.Add(new Span() { SpanID = "span1", Text = "advised to grant", ElementType = SpanType.Undefined, StartIndex = 8, Length = 16 });
            spanList.Add(new Span() { SpanID = "span2", Text = "to grant access to these settings", ElementType = SpanType.Undefined, StartIndex = 16, Length = 33 });
            spanList.Add(new Span() { SpanID = "span3", Text = "these settings only if you", ElementType = SpanType.Undefined, StartIndex = 35, Length = 26 });

            // simple interseciotn
            //spanList.Add(new Span() { SpanID = "span1", Text = "advised to grant", ElementType = TagType.Undefined, StartIndex = 8, Length = 16 });
            //spanList.Add(new Span() { SpanID = "span2", Text = "to grant access", ElementType = TagType.Undefined, StartIndex = 16, Length = 15 });

            // two different spans
            //spanList.Add(new Span() { SpanID = "span1", Text = "advised to grant", ElementType = TagType.Undefined, StartIndex = 8, Length = 16 });
            //spanList.Add(new Span() { SpanID = "span2", Text = "only if you are ", ElementType = TagType.Undefined, StartIndex = 50, Length = 16 });

             // inner span
             //spanList.Add(new Span() { SpanID = "span1", Text = "to grant access to these settings", ElementType = TagType.Undefined  , StartIndex = 16, Length = 33 });
             //spanList.Add(new Span() { SpanID = "span2", Text = "access to these", ElementType = TagType.Undefined, StartIndex = 25, Length = 15 });

            // one inner span, and complex
            //spanList.Add(new Span() { SpanID = "span1", Text = "to grant access to these settings only ", ElementType = TagType.Undefined, StartIndex = 16, Length = 39 });
            //spanList.Add(new Span() { SpanID = "span2", Text = "access to these", ElementType = TagType.Undefined, StartIndex = 25, Length = 15 });
            //spanList.Add(new Span() { SpanID = "span3", Text = "only if you are sure", ElementType = TagType.Undefined, StartIndex = 50, Length = 20 });

            // one large span, and two intersections
            //spanList.Add(new Span() { SpanID = "span1", Text = "grant access to these settings only if you are sure you want to allow this program to run automatically when", ElementType = SpanType.Undefined, StartIndex = 19, Length = 108 });
            //spanList.Add(new Span() { SpanID = "span2", Text = "these settings only", ElementType = SpanType.Undefined, StartIndex = 35, Length = 19 });
            //spanList.Add(new Span() { SpanID = "span3", Text = "you want to allow this", ElementType = SpanType.Undefined, StartIndex = 71, Length = 22 });

            spanList.Sort("StartIndex asc"); 

            foreach (var item in spanList)
                item.SplitSpans(ref spanList, ref intersectionSpanList, ref MessageText);


            // join intersections with span collection
            foreach (var item in intersectionSpanList)
                spanList.Add(item);

            //remove duplicates
            spanList = RemoveDuplicateSpans(spanList);

            // sort spans by index ..
            spanList.Sort("StartIndex asc"); //desc


            foreach (var item in spanList)
            {
                item.InsertStartSpan(ref spanList, ref MessageText);
            }



            foreach (var item in spanList)
            {
                item.InsertEndSpan(ref spanList, ref MessageText);
            }

            //int count = spanList.Count -1;

            //while (count > 0)
            //{
            //    Span currentSpan = spanList[count];
            //    currentSpan.InsertEndSpan(ref spanList, ref MessageText);
            //    count--;
            //} 



        }

        internal static List<Span> RemoveDuplicateSpans(List<Span> list)
        {
            List<int> uniqueList = new List<int>();

            for (int i = 0; i < list.Count; i++)
            {
                for (int j = 0; j < list.Count ; j++)
                {
                    if (list[i].SpanID != list[j].SpanID)
                    { 
                        if (list[i].StartIndex == list[j].StartIndex && list[i].EndPossition == list[j].EndPossition && list[i].ElementType == SpanType.Undefined)
                        {
                            uniqueList.Add(i);
                        }
                    }
                }
            }

            foreach (var item in uniqueList)
            {
                list.RemoveAt(item);
            }

            return list;

        }



    }

    public static class Extensions
    {

        public static void Sort<T>(this List<T> list, string sortExpression)
        {
            string[] sortExpressions = sortExpression.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);

            List<GenericComparer> comparers = new List<GenericComparer>();

            foreach (string sortExpress in sortExpressions)
            {
                string sortProperty = sortExpress.Trim().Split(' ')[0].Trim();
                string sortDirection = sortExpress.Trim().Split(' ')[1].Trim();

                Type type = typeof(T);
                PropertyInfo PropertyInfo = type.GetProperty(sortProperty);
                if (PropertyInfo == null)
                {
                    PropertyInfo[] props = type.GetProperties();
                    foreach (PropertyInfo info in props)
                    {
                        if (info.Name.ToString().ToLower() == sortProperty.ToLower())
                        {
                            PropertyInfo = info;
                            break;
                        }
                    }
                    if (PropertyInfo == null)
                    {
                        throw new Exception(String.Format("{0} is not a valid property of type: \"{1}\"", sortProperty, type.Name));
                    }
                }

                SortDirection SortDirection = SortDirection.Ascending;
                if (sortDirection.ToLower() == "asc" || sortDirection.ToLower() == "ascending")
                {
                    SortDirection = SortDirection.Ascending;
                }
                else if (sortDirection.ToLower() == "desc" || sortDirection.ToLower() == "descending")
                {
                    SortDirection = SortDirection.Descending;
                }
                else
                {
                    throw new Exception("Valid SortDirections are: asc, ascending, desc and descending");
                }

                comparers.Add(new GenericComparer { SortDirection = SortDirection, PropertyInfo = PropertyInfo, comparers = comparers });
            }
            list.Sort(comparers[0].Compare);
        }
    }

    public class GenericComparer
    {
        public List<GenericComparer> comparers { get; set; }
        int level = 0;

        public SortDirection SortDirection { get; set; }
        public PropertyInfo PropertyInfo { get; set; }

        public int Compare<T>(T t1, T t2)
        {
            int ret = 0;

            if (level >= comparers.Count)
                return 0;

            object t1Value = comparers[level].PropertyInfo.GetValue(t1, null);
            object t2Value = comparers[level].PropertyInfo.GetValue(t2, null);

            if (t1 == null || t1Value == null)
            {
                if (t2 == null || t2Value == null)
                {
                    ret = 0;
                }
                else
                {
                    ret = -1;
                }
            }
            else
            {
                if (t2 == null || t2Value == null)
                {
                    ret = 1;
                }
                else
                {
                    ret = ((IComparable)t1Value).CompareTo(((IComparable)t2Value));
                }
            }
            if (ret == 0)
            {
                level += 1;
                ret = Compare(t1, t2);
                level -= 1;
            }
            else
            {
                if (comparers[level].SortDirection == SortDirection.Descending)
                {
                    ret *= -1;
                }
            }
            return ret;
        }
    }

    public class Span
    {
        string _Color = "#F9DA00";

        public const int SPAN_START_LENGTH = 40;
        public const int SPAN_END_LENGTH = 7;
        public const int SPAN_TOTAL_LENGTH = 47;

        public string Color
        {
            get
            {
                return _Color;
            }
            set
            {
                _Color = value;
            }
        }

        public string SpanID { get; set; }

        public int StartIndex { get; set; }

        public int HTMLTagEndPossition { get; set; }

        public Span ParentSpan { get; set; }

        public int Length { get; set; }

        public SpanType ElementType { get; set; }

        public string Text { get; set; }

        public int EndPossition
        {
            get
            {
                return StartIndex + Length;
            }
        }

        public string GetStartSpanHtml()
        {
            return "<span style= 'background-color:" + Color + "'>" + this.Text;
        }

        public string GetEndSpanHtml()
        {
            return "</span>";
        }

        public bool IsProcessed { get; set; }

        internal void PostProcess(Span span, ref List<Span> spanList, ref string MessageText)
        {
            MessageText = MessageText.Remove(span.StartIndex, span.Length);
            MessageText = MessageText.Insert(span.StartIndex, span.GetStartSpanHtml());

            int offset = Span.SPAN_TOTAL_LENGTH;

            AdjustStartOffsetOfSpans(spanList, span, offset);

        }

        internal void SplitSpans(ref List<Span> spanList, ref List<Span> intersectionSpanList, ref string MessageText)
        {
            foreach (var item in spanList)
            {
                if (this.SpanID == item.SpanID)
                    continue;

                if (this.StartIndex < item.StartIndex && this.EndPossition > item.EndPossition)
                { 
                    // inner

                    int innerSpanLength = this.EndPossition - item.StartIndex;
                    int innerSpanStartPos = this.StartIndex;
                    string innerSpanText = MessageText.Substring(item.StartIndex, item.Length);

                    Span innerSpan = new Span();
                    innerSpan.SpanID = "innerSpan" + Guid.NewGuid().ToString().Replace("-", "");
                    innerSpan.ElementType = SpanType.InnerSpan;
                    innerSpan.Text = innerSpanText;
                    innerSpan.Length = item.Length;
                    innerSpan.StartIndex = item.StartIndex;
                    innerSpan.ParentSpan = this;
                    intersectionSpanList.Add(innerSpan);

                }
                if (this.StartIndex < item.StartIndex && item.EndPossition > this.EndPossition && this.EndPossition > item.StartIndex)
                { 
                    // end is overlapping

                    int intersectionLength = this.EndPossition - item.StartIndex;
                    int intersectionStartPos = item.StartIndex;
                    string intersectionText = MessageText.Substring(item.StartIndex, intersectionLength);

                    // Build intersection span
                    Span intersectonSpan = new Span();
                    intersectonSpan.SpanID = "intersectonSpan" + Guid.NewGuid().ToString().Replace("-", "");
                    intersectonSpan.Text = intersectionText;
                    intersectonSpan.Length = intersectionLength;
                    intersectonSpan.StartIndex = intersectionStartPos;
                    intersectonSpan.ElementType = SpanType.Intersection;
                    intersectionSpanList.Add(intersectonSpan);

                    // adjust my end pos.
                    this.Length = this.Length - intersectionLength;
                    this.Text = this.Text.Substring(0, this.Length);

                    item.StartIndex += intersectionLength;
                    item.Length -= intersectionLength;
                    item.Text = item.Text.Substring(intersectionLength, item.Length);

                }
                else if (this.StartIndex < item.StartIndex && item.EndPossition > this.EndPossition && this.EndPossition < item.StartIndex)
                {
                    // two spans are not over lapping,
                }

                //if (this.EndPossition > item.StartIndex && this.EndPossition < item.EndPossition)
                //{

                //    if (item.StartIndex < this.StartIndex && item.EndPossition > this.EndPossition)
                //    {
                //        int innerSpanLength = this.EndPossition - this.StartIndex;
                //        int innerSpanStartPos = this.StartIndex;
                //        string innerSpanText = MessageText.Substring(this.StartIndex, this.Length);


                //        // we are dealing with a inner span..
                //        Span innerSpan = new Span();
                //        innerSpan.SpanID = "innerSpan";
                //        innerSpan.Text = innerSpanText;
                //        innerSpan.Length = innerSpanLength;
                //        innerSpan.StartIndex = innerSpanStartPos;
                //        innerSpan.IsIntersection = true;
                //        intersectionSpanList.Add(innerSpan);

                //        MessageText = MessageText.Remove(innerSpanStartPos, innerSpanLength);
                //        MessageText = MessageText.Insert(innerSpanStartPos, innerSpan.GetStartSpanHtml());
                //        break;
                //    }

                //    int intersectionLength = this.EndPossition - item.StartIndex;
                //    int intersectionStartPos = item.StartIndex;
                //    string intersectionText = MessageText.Substring(item.StartIndex, intersectionLength);


                //    // adjust the string.
                //    if (!this.IsProcessed)
                //    {
                //        this.Text = this.Text.Substring(0, this.Length - intersectionLength);
                //        this.Length = this.Length - intersectionLength;
                //        MessageText = MessageText.Remove(this.StartIndex, this.Length);
                //        MessageText = MessageText.Insert(this.StartIndex, this.GetStartSpanHtml());

                //        // readjust intersection after insertion of the first span..
                //        intersectionStartPos = Span.SPAN_START_LENGTH + intersectionStartPos;
                //    }



                //    // Build intersection span
                //    Span intersectonSpan = new Span();
                //    intersectonSpan.SpanID = "intersectonSpan";
                //    intersectonSpan.Text = intersectionText;
                //    intersectonSpan.Length = intersectionLength;
                //    intersectonSpan.StartIndex = intersectionStartPos;
                //    intersectonSpan.IsIntersection = true;
                //    intersectionSpanList.Add(intersectonSpan);


                //    MessageText = MessageText.Remove(intersectionStartPos, intersectionLength);
                //    MessageText = MessageText.Insert(intersectionStartPos, intersectonSpan.GetStartSpanHtml());

                //    if (!this.IsProcessed)
                //        item.StartIndex = item.StartIndex + intersectionLength + Span.SPAN_START_LENGTH + Span.SPAN_START_LENGTH;
                //    else
                //        item.StartIndex = item.StartIndex + intersectionLength + Span.SPAN_START_LENGTH;

                //    item.Length = item.Length - intersectionLength;
                //    item.Text = item.Text.Substring(intersectionLength, item.Length);

                //    //MessageText = MessageText.Remove(item.StartIndex, item.Length);
                //    //MessageText = MessageText.Insert(item.StartIndex, item.GetOuterHtml());

                //    int offset;

                //    if (!this.IsProcessed)
                //        offset = Span.SPAN_START_LENGTH + Span.SPAN_START_LENGTH;
                //    else
                //        offset = Span.SPAN_START_LENGTH;

                //    AdjustOffsetSpans(spanList, item, offset);

                //    this.IsProcessed = true;

                //    break;
                //}
                //else if (item.StartIndex > this.StartIndex && item.EndPossition < this.EndPossition)
                //{
                //    // bigger span, inside there are children span(s)

                //    MessageText = MessageText.Remove(this.StartIndex, this.Length);
                //    MessageText = MessageText.Insert(this.StartIndex, this.GetStartSpanHtml());

                //    // since this span is the big guy. 

                //    AdjustOffsetForInnerSpansAndExternalSpans(spanList, this, this.StartIndex, this.EndPossition);

                //    this.StartIndex += Span.SPAN_START_LENGTH;
                //    this.IsProcessed = true;
                //}

            }
        }

        //internal static void AdjustOffsetForInnerSpansAndExternalSpans(List<Span> spanList, Span parentSpan, int parentStartIndex, int parentEndIndex)
        //{
        //    bool adjustAfterThisSpan = false;

        //    foreach (var item in spanList)
        //    {
        //        if (item.SpanID == parentSpan.SpanID)
        //        {
        //            adjustAfterThisSpan = true;
        //            continue;
        //        }

        //        if (adjustAfterThisSpan)
        //        {
        //            // is this span in the middle of the parent ?
        //            if (item.StartIndex > parentSpan.StartIndex && item.EndPossition < parentSpan.EndPossition)
        //            {
        //                item.StartIndex += SPAN_START_LENGTH;
        //            }
        //            else
        //            {
        //                // after parent tag ?
        //                item.StartIndex += SPAN_START_LENGTH;
        //            }
        //        }
        //    }
        //}

        private void AdjustEndOffsetOfSpans(List<Span> spanList, Span span, int SPAN_END_LENGTH)
        {
            bool adjustAfterThisSpan = false;

            foreach (var item in spanList)
            {
                if (item.SpanID == span.SpanID)
                {
                    adjustAfterThisSpan = true;
                    continue;
                }

                if (adjustAfterThisSpan)
                {
                    if (item.ParentSpan == null)
                    {
                        item.HTMLTagEndPossition += SPAN_END_LENGTH;

                    }
                    else if (span.ParentSpan != null && this.SpanID == item.ParentSpan.SpanID)
                    { }
                }
            }
        }

        internal static void AdjustStartOffsetOfSpans(List<Span> spanList, Span fromSpan, int offset)
        {
            bool adjustAfterThisSpan = false;

            foreach (var item in spanList)
            {
                if (item.SpanID == fromSpan.SpanID)
                {
                    adjustAfterThisSpan = true;
                    continue;
                }

                if (adjustAfterThisSpan)
                    item.StartIndex += offset;
            }
        }


        internal void InsertStartSpan(ref List<Span> spanList, ref string MessageText)
        {

            MessageText = MessageText.Remove(this.StartIndex, this.Length);
            MessageText = MessageText.Insert(this.StartIndex, this.GetStartSpanHtml());


            AdjustStartOffsetOfSpans(spanList, this, SPAN_START_LENGTH);

            // Adjust end element tag
            switch (this.ElementType)
            {
                case SpanType.Intersection:
                    {
                        this.HTMLTagEndPossition = this.Length + SPAN_START_LENGTH + this.StartIndex;
                        break;
                    }
                case SpanType.InnerSpan:
                    {
                        this.HTMLTagEndPossition = this.Length + SPAN_START_LENGTH + this.StartIndex;

                        // increase the parent's tag offset conent length
                        this.ParentSpan.HTMLTagEndPossition += SPAN_START_LENGTH;
                        break;
                    }
                case SpanType.Undefined:
                    {
                        this.HTMLTagEndPossition = this.Length + SPAN_START_LENGTH + this.StartIndex;
                        break;
                    }
                default:
                    break;
            }




        }

        internal void InsertEndSpan(ref List<Span> spanList, ref string MessageText)
        {
            switch (this.ElementType)
            {
                case SpanType.Intersection:
                    {
                        MessageText = MessageText.Insert(this.HTMLTagEndPossition, this.GetEndSpanHtml());
                        break;
                    }
                case SpanType.InnerSpan:
                    {
                        MessageText = MessageText.Insert(this.HTMLTagEndPossition, this.GetEndSpanHtml());
                        break;
                    }
                case SpanType.Undefined:
                    {
                        MessageText = MessageText.Insert(this.HTMLTagEndPossition, this.GetEndSpanHtml());
                        break;
                    }
                default:
                    break;
            }

            AdjustEndOffsetOfSpans(spanList, this, SPAN_END_LENGTH);


        }


    }

finally manage to find a solution on my own, hope this help someone also in the future

 public enum SortDirection
    {
        Ascending, Descending
    }

    public enum SpanType
    {
        Intersection, InnerSpan, Undefined
    }

    class Program
    {
        static void Main(string[] args)
        {
            string MessageText = @"You are advised to grant access to these settings only if you are sure you want to allow this program to run automatically when your computer starts. Otherwise it is better to deny access.";

            List<Span> spanList = new List<Span>();
            List<Span> intersectionSpanList = new List<Span>();

            spanList.Add(new Span() { SpanID = "span1", Text = "advised to grant", ElementType = SpanType.Undefined, StartIndex = 8, Length = 16 });
            spanList.Add(new Span() { SpanID = "span2", Text = "to grant access to these settings", ElementType = SpanType.Undefined, StartIndex = 16, Length = 33 });
            spanList.Add(new Span() { SpanID = "span3", Text = "these settings only if you", ElementType = SpanType.Undefined, StartIndex = 35, Length = 26 });

            // simple interseciotn
            //spanList.Add(new Span() { SpanID = "span1", Text = "advised to grant", ElementType = TagType.Undefined, StartIndex = 8, Length = 16 });
            //spanList.Add(new Span() { SpanID = "span2", Text = "to grant access", ElementType = TagType.Undefined, StartIndex = 16, Length = 15 });

            // two different spans
            //spanList.Add(new Span() { SpanID = "span1", Text = "advised to grant", ElementType = TagType.Undefined, StartIndex = 8, Length = 16 });
            //spanList.Add(new Span() { SpanID = "span2", Text = "only if you are ", ElementType = TagType.Undefined, StartIndex = 50, Length = 16 });

             // inner span
             //spanList.Add(new Span() { SpanID = "span1", Text = "to grant access to these settings", ElementType = TagType.Undefined  , StartIndex = 16, Length = 33 });
             //spanList.Add(new Span() { SpanID = "span2", Text = "access to these", ElementType = TagType.Undefined, StartIndex = 25, Length = 15 });

            // one inner span, and complex
            //spanList.Add(new Span() { SpanID = "span1", Text = "to grant access to these settings only ", ElementType = TagType.Undefined, StartIndex = 16, Length = 39 });
            //spanList.Add(new Span() { SpanID = "span2", Text = "access to these", ElementType = TagType.Undefined, StartIndex = 25, Length = 15 });
            //spanList.Add(new Span() { SpanID = "span3", Text = "only if you are sure", ElementType = TagType.Undefined, StartIndex = 50, Length = 20 });

            // one large span, and two intersections
            //spanList.Add(new Span() { SpanID = "span1", Text = "grant access to these settings only if you are sure you want to allow this program to run automatically when", ElementType = SpanType.Undefined, StartIndex = 19, Length = 108 });
            //spanList.Add(new Span() { SpanID = "span2", Text = "these settings only", ElementType = SpanType.Undefined, StartIndex = 35, Length = 19 });
            //spanList.Add(new Span() { SpanID = "span3", Text = "you want to allow this", ElementType = SpanType.Undefined, StartIndex = 71, Length = 22 });

            spanList.Sort("StartIndex asc"); 

            foreach (var item in spanList)
                item.SplitSpans(ref spanList, ref intersectionSpanList, ref MessageText);


            // join intersections with span collection
            foreach (var item in intersectionSpanList)
                spanList.Add(item);

            //remove duplicates
            spanList = RemoveDuplicateSpans(spanList);

            // sort spans by index ..
            spanList.Sort("StartIndex asc"); //desc


            foreach (var item in spanList)
            {
                item.InsertStartSpan(ref spanList, ref MessageText);
            }



            foreach (var item in spanList)
            {
                item.InsertEndSpan(ref spanList, ref MessageText);
            }

            //int count = spanList.Count -1;

            //while (count > 0)
            //{
            //    Span currentSpan = spanList[count];
            //    currentSpan.InsertEndSpan(ref spanList, ref MessageText);
            //    count--;
            //} 



        }

        internal static List<Span> RemoveDuplicateSpans(List<Span> list)
        {
            List<int> uniqueList = new List<int>();

            for (int i = 0; i < list.Count; i++)
            {
                for (int j = 0; j < list.Count ; j++)
                {
                    if (list[i].SpanID != list[j].SpanID)
                    { 
                        if (list[i].StartIndex == list[j].StartIndex && list[i].EndPossition == list[j].EndPossition && list[i].ElementType == SpanType.Undefined)
                        {
                            uniqueList.Add(i);
                        }
                    }
                }
            }

            foreach (var item in uniqueList)
            {
                list.RemoveAt(item);
            }

            return list;

        }



    }

    public static class Extensions
    {

        public static void Sort<T>(this List<T> list, string sortExpression)
        {
            string[] sortExpressions = sortExpression.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);

            List<GenericComparer> comparers = new List<GenericComparer>();

            foreach (string sortExpress in sortExpressions)
            {
                string sortProperty = sortExpress.Trim().Split(' ')[0].Trim();
                string sortDirection = sortExpress.Trim().Split(' ')[1].Trim();

                Type type = typeof(T);
                PropertyInfo PropertyInfo = type.GetProperty(sortProperty);
                if (PropertyInfo == null)
                {
                    PropertyInfo[] props = type.GetProperties();
                    foreach (PropertyInfo info in props)
                    {
                        if (info.Name.ToString().ToLower() == sortProperty.ToLower())
                        {
                            PropertyInfo = info;
                            break;
                        }
                    }
                    if (PropertyInfo == null)
                    {
                        throw new Exception(String.Format("{0} is not a valid property of type: \"{1}\"", sortProperty, type.Name));
                    }
                }

                SortDirection SortDirection = SortDirection.Ascending;
                if (sortDirection.ToLower() == "asc" || sortDirection.ToLower() == "ascending")
                {
                    SortDirection = SortDirection.Ascending;
                }
                else if (sortDirection.ToLower() == "desc" || sortDirection.ToLower() == "descending")
                {
                    SortDirection = SortDirection.Descending;
                }
                else
                {
                    throw new Exception("Valid SortDirections are: asc, ascending, desc and descending");
                }

                comparers.Add(new GenericComparer { SortDirection = SortDirection, PropertyInfo = PropertyInfo, comparers = comparers });
            }
            list.Sort(comparers[0].Compare);
        }
    }

    public class GenericComparer
    {
        public List<GenericComparer> comparers { get; set; }
        int level = 0;

        public SortDirection SortDirection { get; set; }
        public PropertyInfo PropertyInfo { get; set; }

        public int Compare<T>(T t1, T t2)
        {
            int ret = 0;

            if (level >= comparers.Count)
                return 0;

            object t1Value = comparers[level].PropertyInfo.GetValue(t1, null);
            object t2Value = comparers[level].PropertyInfo.GetValue(t2, null);

            if (t1 == null || t1Value == null)
            {
                if (t2 == null || t2Value == null)
                {
                    ret = 0;
                }
                else
                {
                    ret = -1;
                }
            }
            else
            {
                if (t2 == null || t2Value == null)
                {
                    ret = 1;
                }
                else
                {
                    ret = ((IComparable)t1Value).CompareTo(((IComparable)t2Value));
                }
            }
            if (ret == 0)
            {
                level += 1;
                ret = Compare(t1, t2);
                level -= 1;
            }
            else
            {
                if (comparers[level].SortDirection == SortDirection.Descending)
                {
                    ret *= -1;
                }
            }
            return ret;
        }
    }

    public class Span
    {
        string _Color = "#F9DA00";

        public const int SPAN_START_LENGTH = 40;
        public const int SPAN_END_LENGTH = 7;
        public const int SPAN_TOTAL_LENGTH = 47;

        public string Color
        {
            get
            {
                return _Color;
            }
            set
            {
                _Color = value;
            }
        }

        public string SpanID { get; set; }

        public int StartIndex { get; set; }

        public int HTMLTagEndPossition { get; set; }

        public Span ParentSpan { get; set; }

        public int Length { get; set; }

        public SpanType ElementType { get; set; }

        public string Text { get; set; }

        public int EndPossition
        {
            get
            {
                return StartIndex + Length;
            }
        }

        public string GetStartSpanHtml()
        {
            return "<span style= 'background-color:" + Color + "'>" + this.Text;
        }

        public string GetEndSpanHtml()
        {
            return "</span>";
        }

        public bool IsProcessed { get; set; }

        internal void PostProcess(Span span, ref List<Span> spanList, ref string MessageText)
        {
            MessageText = MessageText.Remove(span.StartIndex, span.Length);
            MessageText = MessageText.Insert(span.StartIndex, span.GetStartSpanHtml());

            int offset = Span.SPAN_TOTAL_LENGTH;

            AdjustStartOffsetOfSpans(spanList, span, offset);

        }

        internal void SplitSpans(ref List<Span> spanList, ref List<Span> intersectionSpanList, ref string MessageText)
        {
            foreach (var item in spanList)
            {
                if (this.SpanID == item.SpanID)
                    continue;

                if (this.StartIndex < item.StartIndex && this.EndPossition > item.EndPossition)
                { 
                    // inner

                    int innerSpanLength = this.EndPossition - item.StartIndex;
                    int innerSpanStartPos = this.StartIndex;
                    string innerSpanText = MessageText.Substring(item.StartIndex, item.Length);

                    Span innerSpan = new Span();
                    innerSpan.SpanID = "innerSpan" + Guid.NewGuid().ToString().Replace("-", "");
                    innerSpan.ElementType = SpanType.InnerSpan;
                    innerSpan.Text = innerSpanText;
                    innerSpan.Length = item.Length;
                    innerSpan.StartIndex = item.StartIndex;
                    innerSpan.ParentSpan = this;
                    intersectionSpanList.Add(innerSpan);

                }
                if (this.StartIndex < item.StartIndex && item.EndPossition > this.EndPossition && this.EndPossition > item.StartIndex)
                { 
                    // end is overlapping

                    int intersectionLength = this.EndPossition - item.StartIndex;
                    int intersectionStartPos = item.StartIndex;
                    string intersectionText = MessageText.Substring(item.StartIndex, intersectionLength);

                    // Build intersection span
                    Span intersectonSpan = new Span();
                    intersectonSpan.SpanID = "intersectonSpan" + Guid.NewGuid().ToString().Replace("-", "");
                    intersectonSpan.Text = intersectionText;
                    intersectonSpan.Length = intersectionLength;
                    intersectonSpan.StartIndex = intersectionStartPos;
                    intersectonSpan.ElementType = SpanType.Intersection;
                    intersectionSpanList.Add(intersectonSpan);

                    // adjust my end pos.
                    this.Length = this.Length - intersectionLength;
                    this.Text = this.Text.Substring(0, this.Length);

                    item.StartIndex += intersectionLength;
                    item.Length -= intersectionLength;
                    item.Text = item.Text.Substring(intersectionLength, item.Length);

                }
                else if (this.StartIndex < item.StartIndex && item.EndPossition > this.EndPossition && this.EndPossition < item.StartIndex)
                {
                    // two spans are not over lapping,
                }

                //if (this.EndPossition > item.StartIndex && this.EndPossition < item.EndPossition)
                //{

                //    if (item.StartIndex < this.StartIndex && item.EndPossition > this.EndPossition)
                //    {
                //        int innerSpanLength = this.EndPossition - this.StartIndex;
                //        int innerSpanStartPos = this.StartIndex;
                //        string innerSpanText = MessageText.Substring(this.StartIndex, this.Length);


                //        // we are dealing with a inner span..
                //        Span innerSpan = new Span();
                //        innerSpan.SpanID = "innerSpan";
                //        innerSpan.Text = innerSpanText;
                //        innerSpan.Length = innerSpanLength;
                //        innerSpan.StartIndex = innerSpanStartPos;
                //        innerSpan.IsIntersection = true;
                //        intersectionSpanList.Add(innerSpan);

                //        MessageText = MessageText.Remove(innerSpanStartPos, innerSpanLength);
                //        MessageText = MessageText.Insert(innerSpanStartPos, innerSpan.GetStartSpanHtml());
                //        break;
                //    }

                //    int intersectionLength = this.EndPossition - item.StartIndex;
                //    int intersectionStartPos = item.StartIndex;
                //    string intersectionText = MessageText.Substring(item.StartIndex, intersectionLength);


                //    // adjust the string.
                //    if (!this.IsProcessed)
                //    {
                //        this.Text = this.Text.Substring(0, this.Length - intersectionLength);
                //        this.Length = this.Length - intersectionLength;
                //        MessageText = MessageText.Remove(this.StartIndex, this.Length);
                //        MessageText = MessageText.Insert(this.StartIndex, this.GetStartSpanHtml());

                //        // readjust intersection after insertion of the first span..
                //        intersectionStartPos = Span.SPAN_START_LENGTH + intersectionStartPos;
                //    }



                //    // Build intersection span
                //    Span intersectonSpan = new Span();
                //    intersectonSpan.SpanID = "intersectonSpan";
                //    intersectonSpan.Text = intersectionText;
                //    intersectonSpan.Length = intersectionLength;
                //    intersectonSpan.StartIndex = intersectionStartPos;
                //    intersectonSpan.IsIntersection = true;
                //    intersectionSpanList.Add(intersectonSpan);


                //    MessageText = MessageText.Remove(intersectionStartPos, intersectionLength);
                //    MessageText = MessageText.Insert(intersectionStartPos, intersectonSpan.GetStartSpanHtml());

                //    if (!this.IsProcessed)
                //        item.StartIndex = item.StartIndex + intersectionLength + Span.SPAN_START_LENGTH + Span.SPAN_START_LENGTH;
                //    else
                //        item.StartIndex = item.StartIndex + intersectionLength + Span.SPAN_START_LENGTH;

                //    item.Length = item.Length - intersectionLength;
                //    item.Text = item.Text.Substring(intersectionLength, item.Length);

                //    //MessageText = MessageText.Remove(item.StartIndex, item.Length);
                //    //MessageText = MessageText.Insert(item.StartIndex, item.GetOuterHtml());

                //    int offset;

                //    if (!this.IsProcessed)
                //        offset = Span.SPAN_START_LENGTH + Span.SPAN_START_LENGTH;
                //    else
                //        offset = Span.SPAN_START_LENGTH;

                //    AdjustOffsetSpans(spanList, item, offset);

                //    this.IsProcessed = true;

                //    break;
                //}
                //else if (item.StartIndex > this.StartIndex && item.EndPossition < this.EndPossition)
                //{
                //    // bigger span, inside there are children span(s)

                //    MessageText = MessageText.Remove(this.StartIndex, this.Length);
                //    MessageText = MessageText.Insert(this.StartIndex, this.GetStartSpanHtml());

                //    // since this span is the big guy. 

                //    AdjustOffsetForInnerSpansAndExternalSpans(spanList, this, this.StartIndex, this.EndPossition);

                //    this.StartIndex += Span.SPAN_START_LENGTH;
                //    this.IsProcessed = true;
                //}

            }
        }

        //internal static void AdjustOffsetForInnerSpansAndExternalSpans(List<Span> spanList, Span parentSpan, int parentStartIndex, int parentEndIndex)
        //{
        //    bool adjustAfterThisSpan = false;

        //    foreach (var item in spanList)
        //    {
        //        if (item.SpanID == parentSpan.SpanID)
        //        {
        //            adjustAfterThisSpan = true;
        //            continue;
        //        }

        //        if (adjustAfterThisSpan)
        //        {
        //            // is this span in the middle of the parent ?
        //            if (item.StartIndex > parentSpan.StartIndex && item.EndPossition < parentSpan.EndPossition)
        //            {
        //                item.StartIndex += SPAN_START_LENGTH;
        //            }
        //            else
        //            {
        //                // after parent tag ?
        //                item.StartIndex += SPAN_START_LENGTH;
        //            }
        //        }
        //    }
        //}

        private void AdjustEndOffsetOfSpans(List<Span> spanList, Span span, int SPAN_END_LENGTH)
        {
            bool adjustAfterThisSpan = false;

            foreach (var item in spanList)
            {
                if (item.SpanID == span.SpanID)
                {
                    adjustAfterThisSpan = true;
                    continue;
                }

                if (adjustAfterThisSpan)
                {
                    if (item.ParentSpan == null)
                    {
                        item.HTMLTagEndPossition += SPAN_END_LENGTH;

                    }
                    else if (span.ParentSpan != null && this.SpanID == item.ParentSpan.SpanID)
                    { }
                }
            }
        }

        internal static void AdjustStartOffsetOfSpans(List<Span> spanList, Span fromSpan, int offset)
        {
            bool adjustAfterThisSpan = false;

            foreach (var item in spanList)
            {
                if (item.SpanID == fromSpan.SpanID)
                {
                    adjustAfterThisSpan = true;
                    continue;
                }

                if (adjustAfterThisSpan)
                    item.StartIndex += offset;
            }
        }


        internal void InsertStartSpan(ref List<Span> spanList, ref string MessageText)
        {

            MessageText = MessageText.Remove(this.StartIndex, this.Length);
            MessageText = MessageText.Insert(this.StartIndex, this.GetStartSpanHtml());


            AdjustStartOffsetOfSpans(spanList, this, SPAN_START_LENGTH);

            // Adjust end element tag
            switch (this.ElementType)
            {
                case SpanType.Intersection:
                    {
                        this.HTMLTagEndPossition = this.Length + SPAN_START_LENGTH + this.StartIndex;
                        break;
                    }
                case SpanType.InnerSpan:
                    {
                        this.HTMLTagEndPossition = this.Length + SPAN_START_LENGTH + this.StartIndex;

                        // increase the parent's tag offset conent length
                        this.ParentSpan.HTMLTagEndPossition += SPAN_START_LENGTH;
                        break;
                    }
                case SpanType.Undefined:
                    {
                        this.HTMLTagEndPossition = this.Length + SPAN_START_LENGTH + this.StartIndex;
                        break;
                    }
                default:
                    break;
            }




        }

        internal void InsertEndSpan(ref List<Span> spanList, ref string MessageText)
        {
            switch (this.ElementType)
            {
                case SpanType.Intersection:
                    {
                        MessageText = MessageText.Insert(this.HTMLTagEndPossition, this.GetEndSpanHtml());
                        break;
                    }
                case SpanType.InnerSpan:
                    {
                        MessageText = MessageText.Insert(this.HTMLTagEndPossition, this.GetEndSpanHtml());
                        break;
                    }
                case SpanType.Undefined:
                    {
                        MessageText = MessageText.Insert(this.HTMLTagEndPossition, this.GetEndSpanHtml());
                        break;
                    }
                default:
                    break;
            }

            AdjustEndOffsetOfSpans(spanList, this, SPAN_END_LENGTH);


        }


    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文