示例#1
0
        public void TestNormalWrap()
        {
            HTMLDualTagFormatting u = new HTMLDualTagFormatting("uu");
            HTMLDualTagFormatting b = new HTMLDualTagFormatting("b");

            string toTest = "<uu><b>aa</b></uu>";

            WrappedFormat r = new WrappedFormat(u, new Position(4, 13));

            r.AddRule(b, Position.OverlapType.Total);


            Position mod = r.ModifiedPosition;

            Assert.AreEqual(0, mod.Start);

            Assert.AreEqual(2, mod.End);
        }
示例#2
0
        private static void FixDict(Dictionary <TextFormattingRule, ICollection <Position> > dict, WrappedFormat item)
        {
            if (!item.wrappedRules().Any())
            {
                return;
            }

            if (!dict[item.Rule].Remove(item.Position))
            {
                throw new InvalidOperationException("wrapped value is not contained.");
            }

            dict[item.Rule].Add(item.ModifiedPosition);
        }
示例#3
0
        public static result ProcessString(string input, IEnumerable <TextFormattingRule> rules)
        {
            //TODO: This algortihm is terribly complicated due to it being single-pass.
            //Would make more sent to convert to multipass.

            var dict = new Dictionary <TextFormattingRule, ICollection <Position> >();



            List <Tuple <TextFormattingRule, IEnumerator <Position> > > positionEnumerator = generateFirstPositions(rules, input);

            //Potentially, tags can be wrapped:
            //<b><u>...</u></b>
            //<b>aa<u>bb</u>cc</b>dd
            //as this goes through sequentially, in each instance it would be:
            //<b><u>
            //Once u is modifed, b will also need to be shifted as b wraps u.



            var possibleOverlaps = new List <WrappedFormat>();



            string modifiedInput = input;
            int    totalShift    = 0;

            while (positionEnumerator.Count > 0)
            {
                //sort the items
                positionEnumerator.Sort((a, b) => a.Item2.Current.CompareTo(b.Item2.Current));

                IEnumerator <Position> currentEnumerator = positionEnumerator[0].Item2;
                var rule = positionEnumerator[0].Item1;


                //The position in the original string.
                Position toProcess = currentEnumerator.Current;

                //remove any non overlaps from PossibleOverlaps
                totalShift = UpdatePossibleOverlaps(dict, possibleOverlaps, totalShift, rule, toProcess);



                var currentShift = getProcessPosition(possibleOverlaps, toProcess);
                var shiftToUse   = new Tuple <int, int>(currentShift.Item1 + totalShift, currentShift.Item2 + totalShift);

                //The position in the current string.
                Position processPosition = toProcess.Shift(shiftToUse);

                //The position in the string after .Process()
                Position outputPosition = processPosition.Shift(rule.ShiftAmount);


                string newInput = rule.Process(modifiedInput, processPosition);

                Debug.Assert(modifiedInput.Length - newInput.Length == rule.TotalLength);


                //foreach (var overlap in possibleOverlaps)
                //    HandleOverlap(dict, overlap, rule);


                if (!dict.ContainsKey(rule))
                {
                    dict.Add(rule, new List <Position>());
                }

                //Note: This works on the position of the original string, hence using toProcess.
                var wf = new WrappedFormat(rule, outputPosition);
                wf.OriginalPosition = toProcess;
                possibleOverlaps.Add(wf);

                dict[rule].Add(outputPosition);


                if (!currentEnumerator.MoveNext())
                {
                    positionEnumerator.Remove(positionEnumerator[0]);
                }

                modifiedInput = newInput;
            }


            foreach (var item in possibleOverlaps)
            {
                FixDict(dict, item);
            }

            return(new result()
            {
                Value = modifiedInput, Positions = dict
            });
        }