// ReSharper disable once NotNullMemberIsNotInitialized public MarkupNodeReference(MarkupCollection owner, IMarkupDescriptor descriptor, IMarkupData associatedData) { Owner = owner; Descriptor = descriptor; AssociatedData = associatedData; Markup = new Markup(this); }
/// <summary> Marks the given range to have the given markup and data. </summary> /// <exception cref="ArgumentOutOfRangeException"> Thrown when one or more arguments are outside /// the required range. </exception> /// <param name="range"> The range of text to mark. </param> /// <param name="descriptor"> The type of markup to apply to the range. </param> /// <param name="markupData"> The markup data to store with the markup. </param> public Markup MarkRange(Range range, IMarkupDescriptor descriptor, IMarkupData markupData) { if (range.StartIndex < 0) { throw new ArgumentOutOfRangeException(nameof(range)); } if (range.EndIndex > _owner.Length) { throw new ArgumentOutOfRangeException(nameof(range)); } var newFragment = new MarkupNodeReference(this, descriptor, markupData) { Length = range.Length }; int previousNodeAbsoluteIndex; var previousNode = GetClosestNodeBefore(range.StartIndex, out previousNodeAbsoluteIndex); LinkedListNode <MarkupNodeReference> node; if (previousNode == null) { var nextNode = _subFragments.First; if (nextNode != null) { // because we're at the beginning, the offset of the next fragment was an absolute index, thus // we now convert it to a relative index by offsetting our start index. nextNode.Value.RelativeOffsetSinceLastNode -= range.StartIndex; } node = _subFragments.AddFirst(newFragment); newFragment.RelativeOffsetSinceLastNode = range.StartIndex; } else { var nextNode = previousNode.Next; // fix up the next node's relative offset if need be if (nextNode != null) { var nextFragment = nextNode.Value; int absoluteIndexOfNextNode = nextFragment.RelativeOffsetSinceLastNode + previousNodeAbsoluteIndex; nextFragment.RelativeOffsetSinceLastNode = absoluteIndexOfNextNode - range.StartIndex; } newFragment.RelativeOffsetSinceLastNode = range.StartIndex - previousNodeAbsoluteIndex; node = _subFragments.AddAfter(previousNode, newFragment); } newFragment.Node = node; ChangeIndex = ChangeIndex.Next(); return(newFragment.Markup); }