예제 #1
0
파일: Arrow.cs 프로젝트: nofuture-git/31g
        public TextCanvas ComposeArrow(Rule ruler, TextCanvas tc)
        {
            if (ruler == null)
            {
                throw new NoRuleSetException();
            }
            var arrowIdx = ruler.CalcEntryIndex(this);

            Width = tc.Width;

            //find the line on the text canvas
            var ti = tc.Items.FirstOrDefault(t => t.Index == arrowIdx.Item1);

            if (ti == null)
            {
                return(tc);
            }

            //scope in on the ranges for the located line
            TextRange fromTr;

            TryGetTextRange(ti.Ranges, FromBlock.Id, out fromTr);
            TextRange toTr;

            TryGetTextRange(ti.Ranges, ToBlock.Id, out toTr);

            if (fromTr == null || toTr == null)
            {
                return(tc);
            }
            var isOuterBlock = !string.IsNullOrWhiteSpace(tc.Id);

            System.Console.WriteLine(
                $"({(isOuterBlock ? "Outer Block" : "InnerBlock")}) {fromTr.Id} -> {toTr.Id}");

            var arrowText      = new StringBuilder();
            var arrowDirection = DetermineArrowDirection(fromTr.Id, toTr.Id, ti.Ranges);

            switch (arrowDirection)
            {
            case PrintLocation.Left:
                arrowText = GetLeftArrowStrBldr(fromTr, toTr, ti);
                break;

            case PrintLocation.Right:
                arrowText = GetRightArrowStrBldr(fromTr, toTr, ti);
                break;
            }

            tc.Items.First(t => t.Index == arrowIdx.Item1).Text =
                NfString.MergeString(arrowText.ToString(),
                                     new string(tc.Items.First(t => t.Index == arrowIdx.Item1).Text.ToArray())).ToCharArray().ToList();

            return(tc);
        }
예제 #2
0
파일: Block.cs 프로젝트: nofuture-git/31g
        public virtual TextCanvas PrintEntriesOnCanvas()
        {
            if (Ruler == null)
            {
                throw new NoRuleSetException();
            }

            var myCanvas = this.ToTextCanvas(Ruler);

            TextCanvas myInnerBlockCanvas = null;

            if (_innerBlocks.Count > 0)
            {
                myInnerBlockCanvas = _innerBlocks[0].PrintEntriesOnCanvas();
                for (var i = 1; i < _innerBlocks.Count; i++)
                {
                    myInnerBlockCanvas = myInnerBlockCanvas.Concat(_innerBlocks[i].PrintEntriesOnCanvas(), Ruler);
                }
            }

            foreach (var entry in _entries)
            {
                myCanvas = myCanvas.Merge(entry.ToTextCanvas(Ruler), Ruler);
            }

            if (myInnerBlockCanvas != null)
            {
                myCanvas = myCanvas.Merge(myInnerBlockCanvas, Ruler);
            }
            foreach (var arrow in _arrows)
            {
                myCanvas = arrow.ComposeArrow(Ruler, myCanvas);
            }

            myCanvas.Id = Id;
            return(myCanvas);
        }
예제 #3
0
        public static TextCanvas Concat(this TextCanvas block1Tc, TextCanvas block2Tc, Rule ruler)
        {
            if (ruler == null)
            {
                throw new NoRuleSetException();
            }

            if (block2Tc == null)
            {
                return(block1Tc);
            }

            var minIndex      = block1Tc.MinIndex < block2Tc.MinIndex ? block1Tc.MinIndex : block2Tc.MinIndex;
            var maxIndex      = block1Tc.MaxIndex > block2Tc.MaxIndex ? block1Tc.MaxIndex : block2Tc.MaxIndex;
            var blockBarCount = 0;

            Func <char[], bool> printBar =
                c =>
                new string(c).EndsWith($"{Config.GraphChars.Rail}{Config.GraphChars.BarRailIntersect}");

            var tc = new TextCanvas
            {
                MaxIndex = maxIndex,
                Ruler    = ruler,
                MinIndex = minIndex,
                Id       = block1Tc.Id + Config.GraphChars.IDSeparator + block2Tc.Id
            };

            for (var i = minIndex; i <= maxIndex; i++)
            {
                var ti1 = block1Tc.GetTextOrEmpty(i, block1Tc.Width);
                var ti2 = block2Tc.GetTextOrEmpty(i, block2Tc.Width);

                if (ti1.Index < 0 || ti2.Index < 0)
                {
                    continue;
                }

                var ntxt = new List <char>(ti1.Text);
                if (blockBarCount == 1 || block2Tc.MaxIndex >= i)
                {
                    ntxt.Add(Config.GraphChars.Bar);
                }
                else
                {
                    ntxt.Add((char)0x20);
                }

                if (printBar(ti1.Text.ToArray()))
                {
                    blockBarCount += 1;
                }

                var txtRng = new TextRange {
                    Id = block2Tc.Id, Length = ti2.Text.Count, StartIndex = ntxt.Count
                };
                txtRng.InnerRanges.AddRange(ti2.Ranges.Where(x => x.Id != block2Tc.Id));
                ntxt.AddRange(ti2.Text);

                var nti = new TextItem {
                    HashMarkValue = ti1.HashMarkValue, Index = i, Text = ntxt
                };
                nti.Ranges.AddRange(ti1.Ranges);
                nti.Ranges.Add(txtRng);
                tc.Items.Add(nti);

                if (ntxt.Count > tc.Width)
                {
                    tc.Width = ntxt.Count;
                }
            }
            return(tc);
        }
예제 #4
0
        public static TextCanvas ToTextCanvas(this IRuleEntry entry, Rule ruler)
        {
            if (ruler == null)
            {
                throw new NoRuleSetException();
            }

            var entryIndex = ruler.CalcEntryIndex(entry);
            var entryLines = entry.ToString().Split(Config.GraphChars.UNIX_NL_CHAR);

            var ruleIndex = ruler.GetIndexRule();

            //iteration is on this difference so there needs to be at least that many lines in the string
            if (entryIndex.Item2 - entryIndex.Item1 > entryLines.Length)
            {
                throw new DrawingException(
                          string.Format(
                              "Entry is indexed at '{0}' to '{1}', a difference of '{2}' while the entry as a string is composed of '{3}' lines",
                              entryIndex.Item1,
                              entryIndex.Item2,
                              (entryIndex.Item2 - entryIndex.Item1),
                              entryLines.Length));
            }

            var textCanvas = new TextCanvas
            {
                Ruler      = ruler,
                Items      = new List <TextItem>(),
                MinIndex   = entryIndex.Item1,
                MaxIndex   = entryIndex.Item2,
                StartValue = entry.StartValue,
                EndValue   = entry.EndValue,
                Width      = entry.Width,
                Id         = entry.Id
            };

            //single line entry
            if (entryIndex.Item2 == entryIndex.Item1)
            {
                if (entryIndex.Item1 < 0 || entryIndex.Item1 >= ruleIndex.Count)
                {
                    throw new DrawingException(
                              string.Format(
                                  "The entry by ID '{0}' having the text value of '{1}' " +
                                  "is set to a position that is beyond the current ruler's max.",
                                  entry.Id, entry));
                }

                textCanvas.Items.Add(new TextItem
                {
                    HashMarkValue = ruleIndex[entryIndex.Item1],
                    Index         = entryIndex.Item1,
                    Text          = entry.ToString().ToCharArray().ToList()
                });
                return(textCanvas);
            }

            //multiple line entry
            for (var i = entryIndex.Item1; i <= entryIndex.Item2; i++)
            {
                var hashMark = ruleIndex[i];
                var text     = entryLines[(i - entryIndex.Item1)];

                if (string.IsNullOrEmpty(text))
                {
                    continue;
                }
                var nti = new TextItem
                {
                    HashMarkValue = hashMark,
                    Index         = i,
                    Text          = text.ToCharArray().ToList()
                };
                nti.Ranges.Add(new TextRange()
                {
                    Id = entry.Id, Length = nti.Text.Count, StartIndex = 0
                });
                textCanvas.Items.Add(nti);
            }

            return(textCanvas);
        }
예제 #5
0
        public static TextCanvas Merge(this TextCanvas entry1Tc, TextCanvas entry2Tc, Rule ruler)
        {
            //check for null args
            if (ruler == null || entry2Tc == null)
            {
                throw new DrawingException("A merge requires a source, a candidate and a ruler");
            }

            //validate args have something to work with
            if (entry1Tc.IsEmptyItems() && entry2Tc.IsEmptyItems())
            {
                return(new TextCanvas());
            }

            if (entry2Tc.IsEmptyItems() && !entry1Tc.IsEmptyItems())
            {
                return(entry1Tc);
            }

            if (entry1Tc.IsEmptyItems() && !entry2Tc.IsEmptyItems())
            {
                return(entry2Tc);
            }


            //determine total edges for the whole
            var entriesMin = entry1Tc.MinIndex < entry2Tc.MinIndex ? entry1Tc.MinIndex : entry2Tc.MinIndex;
            var entriesMax = entry1Tc.MaxIndex > entry2Tc.MaxIndex ? entry1Tc.MaxIndex : entry2Tc.MaxIndex;

            Func <TextItem, bool> tti = ti1 => ti1 != null && !ti1.IsEmptyText();

            var textCanvas = new TextCanvas
            {
                Ruler    = ruler,
                Items    = new List <TextItem>(),
                MaxIndex = entriesMax,
                MinIndex = entriesMin,
                Width    = entry1Tc.Width > entry2Tc.Width ? entry1Tc.Width : entry2Tc.Width
            };

            for (var i = entriesMin; i <= entriesMax; i++)
            {
                var entry1i = entry1Tc.Items.FirstOrDefault(item => item.Index == i);
                var entry2i = entry2Tc.Items.FirstOrDefault(item => item.Index == i);

                if (entry1i == null && entry2i == null)
                {
                    continue;
                }

                //merge line
                if (tti(entry1i) && tti(entry2i))
                {
                    var newEntry = entry1i.Copy();
                    newEntry.Ranges.AddRange(entry2i.Ranges);
                    newEntry.Text =
                        NfString.MergeString(new string(entry1i.Text.ToArray()), new string(entry2i.Text.ToArray()))
                        .ToCharArray().Where(c => Convert.ToInt32(c) >= 0x20)
                        .ToList();
                    textCanvas.Items.Add(newEntry);

                    continue;
                }

                if (tti(entry1i))
                {
                    textCanvas.Items.Add(entry1i.Copy());
                    continue;
                }
                textCanvas.Items.Add(entry2i.Copy());
            }
            return(textCanvas);
        }
예제 #6
0
        public static TextCanvas ToTextCanvas(this IRuleEntry entry, Rule ruler)
        {
            if(ruler == null)
                throw new NoRuleSetException();

            var entryIndex = ruler.CalcEntryIndex(entry);
            var entryLines = entry.ToString().Split(Config.GraphChars.UNIX_NL_CHAR);

            var ruleIndex = ruler.GetIndexRule();

            //iteration is on this difference so there needs to be at least that many lines in the string
            if (entryIndex.Item2 - entryIndex.Item1 > entryLines.Length)
            {
                throw new DrawingException(
                    string.Format(
                                  "Entry is indexed at '{0}' to '{1}', a difference of '{2}' while the entry as a string is composed of '{3}' lines",
                        entryIndex.Item1,
                        entryIndex.Item2,
                        (entryIndex.Item2 - entryIndex.Item1),
                        entryLines.Length));
            }

            var textCanvas = new TextCanvas
                             {
                                 Ruler = ruler,
                                 Items = new List<TextItem>(),
                                 MinIndex = entryIndex.Item1,
                                 MaxIndex = entryIndex.Item2,
                                 StartValue = entry.StartValue,
                                 EndValue = entry.EndValue,
                                 Width =  entry.Width,
                                 Id = entry.Id
                             };

            //single line entry
            if (entryIndex.Item2 == entryIndex.Item1)
            {
                if (entryIndex.Item1 < 0 || entryIndex.Item1 >= ruleIndex.Count)
                    throw new DrawingException(
                        string.Format(
                            "The entry by ID '{0}' having the text value of '{1}' " +
                            "is set to a position that is beyond the current ruler's max.",
                            entry.Id, entry));

                textCanvas.Items.Add(new TextItem
                                     {
                                         HashMarkValue = ruleIndex[entryIndex.Item1],
                                         Index = entryIndex.Item1,
                                         Text = entry.ToString().ToCharArray().ToList()
                                     });
                return textCanvas;
            }

            //multiple line entry
            for (var i = entryIndex.Item1; i <= entryIndex.Item2; i++)
            {
                var hashMark = ruleIndex[i];
                var text = entryLines[(i - entryIndex.Item1)];

                if (string.IsNullOrEmpty(text))
                    continue;
                var nti = new TextItem
                          {
                              HashMarkValue = hashMark,
                              Index = i,
                              Text = text.ToCharArray().ToList()
                          };
                nti.Ranges.Add(new TextRange(){Id = entry.Id,Length = nti.Text.Count, StartIndex = 0});
                textCanvas.Items.Add(nti);
            }

            return textCanvas;
        }
예제 #7
0
        public static TextCanvas Merge(this TextCanvas entry1Tc, TextCanvas entry2Tc, Rule ruler)
        {
            //check for null args
            if (ruler == null || entry2Tc == null)
                throw new DrawingException("A merge requires a source, a candidate and a ruler");

            //validate args have something to work with
            if(entry1Tc.IsEmptyItems() && entry2Tc.IsEmptyItems())
                return new TextCanvas();

            if (entry2Tc.IsEmptyItems() && !entry1Tc.IsEmptyItems())
                return entry1Tc;

            if (entry1Tc.IsEmptyItems() && !entry2Tc.IsEmptyItems())
                return entry2Tc;

            //determine total edges for the whole
            var entriesMin = entry1Tc.MinIndex < entry2Tc.MinIndex ? entry1Tc.MinIndex : entry2Tc.MinIndex;
            var entriesMax = entry1Tc.MaxIndex > entry2Tc.MaxIndex ? entry1Tc.MaxIndex : entry2Tc.MaxIndex;

            Func<TextItem, bool> tti = ti1 => ti1 != null && !ti1.IsEmptyText();

            var textCanvas = new TextCanvas
                             {
                                 Ruler = ruler,
                                 Items = new List<TextItem>(),
                                 MaxIndex = entriesMax,
                                 MinIndex = entriesMin,
                                 Width = entry1Tc.Width > entry2Tc.Width ? entry1Tc.Width : entry2Tc.Width
                             };
            for (var i = entriesMin; i <= entriesMax; i++)
            {
                var entry1i = entry1Tc.Items.FirstOrDefault(item => item.Index == i);
                var entry2i = entry2Tc.Items.FirstOrDefault(item => item.Index == i);

                if (entry1i == null && entry2i == null)
                    continue;

                //merge line
                if (tti(entry1i) && tti(entry2i))
                {
                    var newEntry = entry1i.Copy();
                    newEntry.Ranges.AddRange(entry2i.Ranges);
                    newEntry.Text =
                        Etc.MergeString(new string(entry1i.Text.ToArray()), new string(entry2i.Text.ToArray()))
                            .ToCharArray().Where(c => Convert.ToInt32(c) >= 0x20)
                            .ToList();
                    textCanvas.Items.Add(newEntry);

                    continue;
                }
                else if (tti(entry1i))
                {
                    textCanvas.Items.Add(entry1i.Copy());
                    continue;
                }
                textCanvas.Items.Add(entry2i.Copy());

            }
            return textCanvas;
        }
예제 #8
0
        public static TextCanvas Concat(this TextCanvas block1Tc, TextCanvas block2Tc, Rule ruler)
        {
            if(ruler == null)
                throw new NoRuleSetException();

            if (block2Tc == null)
            {
                return block1Tc;
            }

            var minIndex = block1Tc.MinIndex < block2Tc.MinIndex ? block1Tc.MinIndex : block2Tc.MinIndex;
            var maxIndex = block1Tc.MaxIndex > block2Tc.MaxIndex ? block1Tc.MaxIndex : block2Tc.MaxIndex;
            var blockBarCount = 0;

            Func<char[], bool> printBar =
                c =>
                    new String(c).EndsWith(string.Format("{0}{1}",
                        Config.GraphChars.Rail,
                        Config.GraphChars.BarRailIntersect));

            var tc = new TextCanvas() { MaxIndex = maxIndex, Ruler = ruler, MinIndex = minIndex, Id = block1Tc.Id + Config.GraphChars.IDSeparator + block2Tc.Id };
            for (var i = minIndex; i <= maxIndex; i++)
            {
                var ti1 = block1Tc.GetTextOrEmpty(i, block1Tc.Width);
                var ti2 = block2Tc.GetTextOrEmpty(i, block2Tc.Width);

                if (ti1.Index < 0 || ti2.Index < 0)
                    continue;

                var ntxt = new List<char>(ti1.Text);
                if (blockBarCount == 1 || block2Tc.MaxIndex >= i)
                    ntxt.Add(Config.GraphChars.Bar);
                else
                    ntxt.Add((char)0x20);

                if (printBar(ti1.Text.ToArray()))
                    blockBarCount += 1;

                var txtRng = new TextRange() {Id = block2Tc.Id, Length = ti2.Text.Count, StartIndex = ntxt.Count};
                ntxt.AddRange(ti2.Text);

                var nti = new TextItem() {HashMarkValue = ti1.HashMarkValue, Index = i, Text = ntxt};
                nti.Ranges.AddRange(ti1.Ranges);
                nti.Ranges.Add(txtRng);
                tc.Items.Add(nti);

                if (ntxt.Count > tc.Width)
                    tc.Width = ntxt.Count;
            }
            return tc;
        }
예제 #9
0
        public TextCanvas ComposeArrow(Rule ruler, TextCanvas tc)
        {
            if (ruler == null)
                throw new NoRuleSetException();
            var arrowIdx = ruler.CalcEntryIndex(this);

            //find the line on the text canvas
            var ti = tc.Items.FirstOrDefault(t => t.Index == arrowIdx.Item1);
            if (ti == null)
                return tc;

            //scope in on the ranges for the located line
            var fromTr = ti.Ranges.FirstOrDefault(tr => tr.Id == FromBlock.Id);
            var toTr = ti.Ranges.FirstOrDefault(tr => tr.Id == ToBlock.Id);

            if (fromTr == null || toTr == null)
                return tc;
            var arrowText = new StringBuilder();
            var arrowDirection = DetermineArrowDirection(fromTr.Id, toTr.Id, ti.Ranges);
            if (arrowDirection == PrintLocation.Left)
            {
                var leftTr = fromTr;
                var rightTr = toTr;
                var aPriorLen = String.IsNullOrWhiteSpace(ExcludedRangeId)
                    ? GetLeftAPriorLen(leftTr.Id, ti.Ranges)
                    : GetLeftAPriorLen(leftTr.Id, ti.Ranges, ExcludedRangeId);

                var betwixtLen = GetRangeLenBetwixt(leftTr.Id, rightTr.Id, ti.Ranges);
                arrowText = ComposeToRightArrow(betwixtLen, aPriorLen, leftTr.Length, Text, rightTr.Length);
            }
            else if (arrowDirection == PrintLocation.Right)
            {
                var leftTr = toTr;
                var rightTr = fromTr;
                var aPriorLen = String.IsNullOrWhiteSpace(ExcludedRangeId)
                    ? GetLeftAPriorLen(leftTr.Id, ti.Ranges)
                    : GetLeftAPriorLen(leftTr.Id, ti.Ranges, ExcludedRangeId);
                var betwixtLen = GetRangeLenBetwixt(leftTr.Id, rightTr.Id, ti.Ranges);
                arrowText = ComposeToLeftArrow(betwixtLen, aPriorLen, leftTr.Length, Text);
            }

            tc.Items.First(t => t.Index == arrowIdx.Item1).Text =
                Etc.MergeString(arrowText.ToString(),
                    new string(tc.Items.First(t => t.Index == arrowIdx.Item1).Text.ToArray())).ToCharArray().ToList();

            return tc;
        }