Example #1
0
        /// <summary>Do a comparison to determine the relative order of <paramref name="aDescendant"/> and <paramref name="anotherDescendant"/></summary>
        /// <remarks>This method is invoked by the CompareTo method that implements IComparable for PartOfSpeechBuilder.  Because this method is invoked
        /// on the most recent common ancestor of <paramref name="aDescendantPartOfSpeech"/> and <paramref name="anotherDescendantPartOfSpeech"/>, finding
        /// the ordering of those descendant parts of speech is equivalent to finding the ordering of the children of this common ancestor which are
        /// respective ancestors of those parts of speech.</remarks>
        public int CompareDescendants(IElementTreeNode aDescendant, IElementTreeNode anotherDescendant)
        {
            IElementTreeNode childAncestorOfADescendant       = Children.Where(child => aDescendant.IsInSubtreeOf(child)).Single();
            IElementTreeNode childAncestorOfAnotherDescendant = Children.Where(child => anotherDescendant.IsInSubtreeOf(child)).Single();
            IElementTreeNode childToLookFor;

            // See if we can find a chain of ChildOrdering that connects aChild to anotherChild, in Before -> After order
            childToLookFor = childAncestorOfADescendant;
            do
            {
                ChildOrdering link = ChildOrderings.Where(ordering => ordering.Before == childToLookFor).FirstOrDefault();
                if (link == null)   // We're at the end of the chain and it didn't lead to what we're looking for
                {
                    break;          // Out of the do loop
                }
                else
                {
                    if (link.After == childAncestorOfAnotherDescendant)
                    {
                        return(-1);                                                 // We found the chain we were looking for
                    }
                    else
                    {
                        childToLookFor = link.After;            // Keep following the chain
                    }
                }
            } while (true);
            // We failed to find a chain connecting aChild to anotherChild in Before -> After order.
            // Now we'll see if such a chain exists in After -> Before order
            childToLookFor = childAncestorOfADescendant;
            do
            {
                ChildOrdering link = ChildOrderings.Where(ordering => ordering.After == childToLookFor).FirstOrDefault();
                if (link == null)   // We're at the end of the chain and it didn't lead to what we're looking for
                {
                    break;          // Out of the do loop
                }
                else
                {
                    if (link.Before == childAncestorOfAnotherDescendant)
                    {
                        return(1);                                                  // We found the chain we were looking for
                    }
                    else
                    {
                        childToLookFor = link.Before;           // Keep following the chain
                    }
                }
            } while (true);
            // We couldn't find a chain between these two IElementTreeNodes in either direction.
            // As far as this parent is concerned, they are equal.
            return(0);
        }
Example #2
0
        /// <summary>Remove any ChildOrderings that refer to <paramref name="child"/>.</summary>
        private protected void RemoveChildOrderingsThatReferTo(IElementTreeNode child)
        {
            ChildOrdering orderingWithTheRemovedChildAsBefore = ChildOrderings.FirstOrDefault(ordering => ordering.Before == child);
            ChildOrdering orderingWithTheRemovedChildAsAfter  = ChildOrderings.FirstOrDefault(ordering => ordering.After == child);

            if (orderingWithTheRemovedChildAsBefore != null)
            {
                if (orderingWithTheRemovedChildAsAfter != null) // The removed child is between two other children
                {
                    orderingWithTheRemovedChildAsBefore.Before = orderingWithTheRemovedChildAsAfter.Before;
                    ChildOrderings.Remove(orderingWithTheRemovedChildAsAfter);
                }
                else
                {
                    ChildOrderings.Remove(orderingWithTheRemovedChildAsBefore);   // The removed child has no other children before it
                }
            }
            else
            {
                ChildOrderings.Remove(orderingWithTheRemovedChildAsAfter);   // The removed child has no other children after it
            }
        }
Example #3
0
        /// <summary>Configure the ChildOrderings of this ParentElementBuilder so <paramref name="childToOrder"/> has relation <paramref name="relation"/> to <paramref name="childToOrderRelativeTo"/>.</summary>
        public void SetChildOrdering(IElementTreeNode childToOrder, IElementTreeNode childToOrderRelativeTo, NodeRelation relation)
        {
            switch (relation)
            {
            case NodeRelation.First:
                IElementTreeNode firstExistingChild = Children.OrderBy(child => child).FirstOrDefault(child => !ChildOrderings.Any(ordering => ordering.After == child));
                if (firstExistingChild != null)
                {
                    ChildOrderings.Add(new ChildOrdering {
                        Before = childToOrder, After = firstExistingChild
                    });
                }
                break;

            case NodeRelation.Before:
                ChildOrdering existingOrderingBeforeRelativeChild = ChildOrderings.FirstOrDefault(ordering => ordering.After == childToOrderRelativeTo);
                if (existingOrderingBeforeRelativeChild != null)
                {
                    ChildOrderings.Add(new ChildOrdering {
                        Before = childToOrder, After = existingOrderingBeforeRelativeChild.After
                    });
                    existingOrderingBeforeRelativeChild.After = childToOrder;
                }
                else
                {
                    ChildOrderings.Add(new ChildOrdering {
                        Before = childToOrder, After = childToOrderRelativeTo
                    });
                }
                break;

            case NodeRelation.After:
                ChildOrdering existingOrderingAfterRelativeChild = ChildOrderings.FirstOrDefault(ordering => ordering.Before == childToOrderRelativeTo);
                if (existingOrderingAfterRelativeChild != null)
                {
                    ChildOrderings.Add(new ChildOrdering {
                        Before = existingOrderingAfterRelativeChild.Before, After = childToOrder
                    });
                    existingOrderingAfterRelativeChild.Before = childToOrder;
                }
                else
                {
                    ChildOrderings.Add(new ChildOrdering {
                        Before = childToOrderRelativeTo, After = childToOrder
                    });
                }
                break;

            case NodeRelation.Last:
                IElementTreeNode lastExistingChild = Children.OrderBy(child => child).FirstOrDefault(child => !ChildOrderings.Any(ordering => ordering.Before == child));
                if (lastExistingChild != null)
                {
                    ChildOrderings.Add(new ChildOrdering {
                        Before = lastExistingChild, After = childToOrder
                    });
                }
                break;

            default: throw new ArgumentException("Unhandled relation type while trying to set ChildOrdering");
            }
        }