예제 #1
0
        /// <summary>
        ///     Destructively Copies the whole MarkupString Structure into the given MarkupString Object.
        /// </summary>
        /// <param name="newMarkupString">The MarkupString object to copy into.</param>
        /// <returns>The newMarkupString, now filled with this MarkupString's information.</returns>
        public MarkupString CopyInto(MarkupString newMarkupString)
        {
            if (this.IsString())
            {
                newMarkupString.beneathList  = null;
                newMarkupString.stringWeight = null;
                newMarkupString.MyMarkup     = null;
                newMarkupString.bareString   = new StringBuilder();
                newMarkupString.bareString.Append(this.bareString);
                return(newMarkupString);
            }

            // Implied else.
            newMarkupString.beneathList  = new List <MarkupString>();
            newMarkupString.stringWeight = new List <int>();
            newMarkupString.MyMarkup     = new Markup(this.MyMarkup);
            foreach (MarkupString mySubMarkupString in this.beneathList)
            {
                newMarkupString.bareString = null;
                var thisOne = new MarkupString();
                newMarkupString.beneathList.Add(mySubMarkupString.CopyInto(thisOne));
                newMarkupString.stringWeight.Add(thisOne.Weight());
            }

            return(newMarkupString);
        }
예제 #2
0
        /// <summary>
        ///     An edit function that replaces the position->range with a copy of the new MarkupString.
        /// </summary>
        /// <param name="newMarkupString">The new MarkupString to copy and insert into this structure.</param>
        /// <param name="position">The position where the edit begins, based on an insert position.</param>
        /// <param name="length">The length of string to 'replace' with this edit.</param>
        /// <returns>The MarkupString itself.</returns>
        public MarkupString Replace(MarkupString newMarkupString, int position, int length)
        {
            var replacement = new MarkupString(newMarkupString);

            Insert(replacement, position);
            Remove(position + replacement.Weight(), length);
            return(this);
        }
예제 #3
0
        /// <summary>
        ///     Initializes a new instance of the <see cref="FunctionResult" /> class, along with a copy of the MarkupString given.
        /// </summary>
        /// <param name="markupString">The MarkupString to insert into the Result.</param>
        public FunctionResult(MarkupString markupString = null)
        {
            if (markupString == null)
            {
                this.results.Add(new MarkupString(string.Empty));
                return;
            }

            this.results.Add(new MarkupString(markupString));
        }
예제 #4
0
        /// <summary>
        ///     This function returns the position of the MarkupString after concatenating two existing ones.
        ///     <remarks>It is up to another function to link this result in properly.</remarks>
        /// </summary>
        /// <param name="left">MarkupString on the left.</param>
        /// <param name="right">MarkupString on the right.</param>
        /// <returns>A MarkupString that simply has concatenated the two MarkupStrings.</returns>
        public MarkupString Concat(MarkupString left, MarkupString right)
        {
            var newMarkupString = new MarkupString();

            newMarkupString.beneathList.Add(left);
            newMarkupString.stringWeight.Add(left.Weight());

            newMarkupString.beneathList.Add(right);
            newMarkupString.stringWeight.Add(right.Weight());

            return(newMarkupString);
        }
예제 #5
0
 /// <summary>
 ///     Implementation of flattening the MarkupString. This assumes the wrapper has given us a mixed markup for the first
 ///     step.
 /// </summary>
 /// <param name="markupStringList">A reference to a markupStringList to put the generated MarkupString instances into.</param>
 /// <param name="mup">The Markup of our parent to Markup.Mix()</param>
 private void FlattenInto(ref List <MarkupString> markupStringList, Markup mup)
 {
     if (!this.IsString())
     {
         foreach (MarkupString each in this.beneathList)
         {
             each.FlattenInto(ref markupStringList, this.MyMarkup.Mix(mup));
         }
     }
     else
     {
         var myMarkupParent = new MarkupString(mup);
         myMarkupParent.Insert(this.bareString.ToString(), 0);
         markupStringList.Add(myMarkupParent);
     }
 }
예제 #6
0
        /// <summary>
        ///     The work-horse for destructively copying a substring set of a MarkupString into the given MarkupString object.
        /// </summary>
        /// <param name="newMarkupString">The MarkupString object to copy into.</param>
        /// <param name="position">The zero-based starting character position in this instance.</param>
        /// <param name="length">The number of characters in the substring.</param>
        private void CopySubstringInto(MarkupString newMarkupString, int position, int length)
        {
            if (this.IsString())
            {
                newMarkupString.MyMarkup     = null;
                newMarkupString.beneathList  = null;
                newMarkupString.stringWeight = null;
                newMarkupString.bareString   = new StringBuilder(this.bareString.ToString().Substring(position, length));
            }
            else
            {
                newMarkupString.MyMarkup     = new Markup(this.MyMarkup);
                newMarkupString.beneathList  = new List <MarkupString>();
                newMarkupString.stringWeight = new List <int>();
                newMarkupString.bareString   = null;

                // We can't do this in parallel. Must be done in-order.
                foreach (MarkupString markupStringItem in this.beneathList)
                {
                    // We're done if we have nothing else to add to the substring node.
                    if (length <= 0)
                    {
                        break;
                    }

                    // If the weight is less than the position, or equal to, this is not where we want to copy from.
                    // So reduce the relative-position and try again.
                    if (markupStringItem.Weight() <= position)
                    {
                        position -= markupStringItem.Weight();
                        continue;
                    }

                    int maxCut = markupStringItem.Weight() - position;
                    int curCut = maxCut < length ? maxCut : length;

                    var thisOne = new MarkupString();
                    markupStringItem.CopySubstringInto(thisOne, position, curCut);

                    newMarkupString.beneathList.Add(thisOne);
                    newMarkupString.stringWeight.Add(thisOne.Weight());

                    length  -= curCut;
                    position = 0;
                }
            }
        }
예제 #7
0
 /// <summary>
 ///     Initializes a new instance of the <see cref="MarkupString" /> class, copied from the object given, based on
 ///     position and length. This is also known as the Substring copy constructor.
 /// </summary>
 /// <param name="copyFrom">The MarkupString node to assumed to be root - and copy from.</param>
 /// <param name="position">What character position (0 based) to start the copy from.</param>
 /// <param name="length">How many characters to copy.</param>
 public MarkupString(MarkupString copyFrom, int position, int length)
 {
     copyFrom.CopySubstringInto(this, position, length);
 }
예제 #8
0
 /// <summary>
 ///     Initializes a new instance of the <see cref="MarkupString" /> class, copied from the object given.
 /// </summary>
 /// <param name="copyFrom">The MarkupString node to assumed to be root - and copy from.</param>
 public MarkupString(MarkupString copyFrom)
 {
     copyFrom.CopyInto(this);
 }
예제 #9
0
        /// <summary>
        /// StringTest tests strings. To be converted into a UnitTest later.
        /// </summary>
        public static void StringTest()
        {
            Console.Read();

            const MarkupRule hiLite = MarkupRule.HiLight;
            var hiLiteAsList        = new HashSet <MarkupRule> {
                hiLite
            };
            var testString1 = new MarkupString(new Markup(hiLiteAsList));
            var testString2 = new MarkupString();

            /* ----------------------------------
             *  Testing Ansi Insert and Remove
             * ---------------------------------- */
            Console.WriteLine("Inserting DOOD into HiLite markup string 1 at position 0.");
            testString1.Insert("DOOD", 0);
            Console.WriteLine("Inserting Omnomnom into markup string 2 at position 0.");
            testString2.Insert("Omnomnom", 0);
            Console.WriteLine("Inserting markup string 1 into markup string 2 at position 4.");
            testString2.Insert(testString1, 4);
            Console.WriteLine("Printing markup string 2: ");
            Console.WriteLine(testString2.ToString());
            Console.WriteLine("Removing 4 characters starting at position 3 from markup string 2.");
            testString2.Remove(3, 4);
            Console.WriteLine("Printing markup string 2: ");
            Console.WriteLine(testString2.ToString());

            /* ----------------------------------
             *  Testing Ansi Flattening
             * ---------------------------------- */
            Console.WriteLine("Ansi Flattening Tests");
            var testString3 = new List <MarkupString>();

            testString2.FlattenInto(ref testString3);

            Console.WriteLine("Flattening string 2 into string 3, and printing.");
            Console.WriteLine(testString2.ToString());

            var sb2 = new StringBuilder();

            foreach (MarkupString each in testString3)
            {
                sb2.Append(each.ToTestString());
            }

            Console.WriteLine(sb2.ToString());
            Console.WriteLine("\n\n\n");
            Console.ReadLine();


            Console.WriteLine("Creating string 4 from string 2 (" + testString2 + "), starting at position 2, length 4.");
            var testString4 = new MarkupString(testString2, 2, 4);

            Console.WriteLine(testString4.ToString());

            Console.WriteLine("\nInserting 'Graaaa' into string 4 at position 2.");
            testString4.Insert("Graaaa", 2);

            Console.WriteLine("Printing test string 4");
            Console.WriteLine(testString4);

            Console.WriteLine("Replacing string 4 at position 3 for length 4 with 'IttyBittyKittyCommitty'");
            testString4.Replace(new MarkupString("IttyBittyKittyCommitty"), 3, 4);
            Console.WriteLine("Printing test string 4");
            Console.WriteLine(testString4);

            Console.WriteLine("Replacing string 4 at position 4 for length 2 with string 2 (" + testString2 + ")");
            testString4.Replace(testString2, 4, 2);
            Console.WriteLine("Printing test string 4");
            Console.WriteLine(testString4);
            Console.ReadLine();
        }
예제 #10
0
 /// <summary>
 ///     Appends a MarkupString to the end of this instance of MarkupString.
 /// </summary>
 /// <param name="markupStringArg">The MarkupString being added to this instance.</param>
 /// <returns>The MarkupString itself.</returns>
 public MarkupString Append(MarkupString markupStringArg)
 {
     beneathList.Add(markupStringArg);
     stringWeight.Add(markupStringArg.Weight());
     return(this);
 }
예제 #11
0
        /// <summary>
        ///     The InsertString will put markupStringArg into the position in the MarkupString structure.
        ///     To do this, it may split up a string beneath it. After all, the node is expected to be Marked Up.
        /// </summary>
        /// <param name="markupStringArg">The MarkupString to insert. Please make sure to give it a Copy!</param>
        /// <param name="position">The position into which to insert. See remarks for insertion logic.</param>
        /// <returns>The MarkupString itself.</returns>
        public MarkupString Insert(MarkupString markupStringArg, int position)
        {
            if (IsString())
            {
                beneathList  = new List <MarkupString>();
                stringWeight = new List <int>();
                MyMarkup     = new Markup(); // Blank Markup Transition

                var rightside = bareString.ToString().Substring(position);
                var leftside  = bareString.ToString().Substring(0, bareString.Length - rightside.Length);

                beneathList.Add(new MarkupString(leftside));
                beneathList.Add(new MarkupString(markupStringArg));
                beneathList.Add(new MarkupString(rightside));

                bareString = null;

                stringWeight.Add(beneathList[0].Weight());
                stringWeight.Add(beneathList[1].Weight());
                stringWeight.Add(beneathList[2].Weight());
            }
            else
            {
                var targetPosition = position;

                // We need to find the way this string is now 'split', and leave the 'remainder' up to another call of InsertString.
                var passedWeights = stringWeight.TakeWhile(val => (targetPosition -= val) >= 0).Count();

                /* Warning: here, a position of 3 generates a targetPosition of -5 after noticing a weight 8. The position it needs to
                 *  go into is 3. But had it passed over a weight of 2, the targetposition would be '1' for the /next/ unit. Which is correct.
                 *
                 * But if that had a weight of 4, it'd end up being 1-4 = -3. We need to re-add the last step, on which the evaluation failed.
                 */
                if (targetPosition == 0)
                {
                    // We must place it 'between', at the beginning, or at the 'end' of a beneathList.
                    // We know how many elements in we should be... so:
                    // If count is at 0, it's an insert.
                    // If count is equal to stringWeight.Count, append at end.
                    // Otherwise, pass the new targetPosition to insert into the String.
                    beneathList.Insert(passedWeights, markupStringArg);
                    stringWeight.Insert(passedWeights, markupStringArg.Weight());
                }
                else
                {
                    // This is the adjustment for the 'last step reduction' error.
                    targetPosition += stringWeight[passedWeights];

                    beneathList[passedWeights].Insert(markupStringArg, targetPosition);
                    stringWeight[passedWeights] += markupStringArg.Weight();

                    if (!beneathList[passedWeights].MyMarkup.IsOnlyInherit())
                    {
                        return(this);
                    }

                    // If the below is now an empty (OnlyInherit) Markup, we can 'pull it up'.
                    // That is to say, we can put its individual beneathLists in the position where we had our old one.
                    // If the item below is not an empty (OnlyInherit) Markup, then it wasn't the item below that we did
                    // the final insert into.
                    var reference = beneathList[passedWeights];
                    beneathList.RemoveAt(passedWeights);
                    stringWeight.RemoveAt(passedWeights);
                    beneathList.InsertRange(passedWeights, reference.beneathList);
                    stringWeight.InsertRange(passedWeights, reference.stringWeight);
                }
            }

            return(this);
        }