Пример #1
0
 internal PrependBlocksAction(ContainerBlock parent, Block beforeChild)
     : base(beforeChild.Root)
 {
     Param.CheckNotNull(beforeChild, "beforeChild");
     BeforeChild = beforeChild;
     Parent      = parent;
 }
        private static ContainerOrTerminalNode ParseBlock(ContainerBlock block, CharacterPositionFinder finder, TextProvider textProvider)
        {
            var name         = GetName(block, textProvider);
            var type         = GetType(block);
            var locationSpan = GetLocationSpan(block, finder);

            var container = new Container
            {
                Type         = type,
                Name         = name,
                LocationSpan = locationSpan,
                HeaderSpan   = GetHeaderSpan(block),
                FooterSpan   = GetFooterSpan(block),
            };

            if (block is ListBlock list)
            {
                foreach (var listItem in list)
                {
                    var item = ParseBlock(listItem, finder, textProvider);
                    container.Children.Add(item);
                }
            }

            // TODO: RKN
            // - Table
            // - ListBlock

            // check whether we can use a terminal node instead
            var child = FinalAdjustAfterParsingComplete(container);

            return(child);
        }
Пример #3
0
 public void ParseItemProperties(string source, Item item, ContainerBlock blocks)
 {
     foreach (var block in blocks)
     {
         ParseItemProperties(source, item, block);
     }
 }
Пример #4
0
        /// <summary>
        /// Writes the children of the specified <see cref="ContainerBlock"/>.
        /// </summary>
        /// <param name="containerBlock">The container block.</param>
        public void WriteChildren(ContainerBlock containerBlock)
        {
            if (containerBlock == null)
            {
                return;
            }

            ThrowHelper.CheckDepthLimit(childrenDepth++);

            bool saveIsFirstInContainer = IsFirstInContainer;
            bool saveIsLastInContainer  = IsLastInContainer;

            var children = containerBlock;

            for (int i = 0; i < children.Count; i++)
            {
                IsFirstInContainer = i == 0;
                IsLastInContainer  = i + 1 == children.Count;
                Write(children[i]);
            }

            IsFirstInContainer = saveIsFirstInContainer;
            IsLastInContainer  = saveIsLastInContainer;

            childrenDepth--;
        }
Пример #5
0
        public static int GetHeadingLevel(this Block block)
        {
            ContainerBlock parent = block.Parent;

            if (parent != null)
            {
                int index = parent.IndexOf(block);
                for (int i = index; i > -1; i--)
                {
                    if (parent[i] is HeadingBlock headingBlock)
                    {
                        return(headingBlock.Level);
                    }
                }
            }
            if (block is ContainerBlock containerBlock)
            {
                int level = 7;
                foreach (var child in containerBlock)
                {
                    if (child is HeadingBlock headingBlock)
                    {
                        if (headingBlock.Level < level)
                        {
                            level = headingBlock.Level;
                        }
                    }
                }
                return(level == 7 ? 0 : level);
            }

            return(0);
        }
Пример #6
0
        public void MoveChildren_ThrowsBlockExceptionIfAChildIsNotOfTheExpectedType()
        {
            // Arrange
            const int dummyLineIndex   = 6;
            const int dummyColumn      = 2;
            var       dummyChildBlock1 = new DummyChildBlock(null);
            Block     dummyChildBlock2 = _mockRepository.Create <Block>(null).Object;
            var       dummyChildBlock3 = new DummyChildBlock(null);
            var       dummyProxyFencedContainerBlock = new ProxyFencedContainerBlock(0, 0, null, null)
            {
                dummyChildBlock1, dummyChildBlock2, dummyChildBlock3
            };
            ContainerBlock dummyTarget = _mockRepository.Create <ContainerBlock>(null).Object;

            dummyTarget.Column = dummyColumn;
            dummyTarget.Line   = dummyLineIndex;
            ExposedCollectionBlockFactory testSubject = CreateExposedCollectionBlockFactory();

            // Act and assert
            BlockException result = Assert.Throws <BlockException>(() => testSubject.ExposedMoveChildren(dummyProxyFencedContainerBlock, dummyTarget));

            Assert.Equal(string.Format(Strings.BlockException_BlockException_InvalidBlock,
                                       dummyTarget.GetType().Name,
                                       dummyLineIndex + 1,
                                       dummyColumn,
                                       string.Format(Strings.BlockException_Shared_BlockMustOnlyContainASpecificTypeOfBlock,
                                                     nameof(ContainerBlock),
                                                     nameof(DummyChildBlock),
                                                     dummyChildBlock2.GetType().Name)),
                         result.Message);
        }
Пример #7
0
        private void OnHeadingBlockParsed(BlockProcessor processor, Block block)
        {
            if (!(block is HeadingBlock headingBlock) || block is BlogMetadataBlock)
            {
                return;
            }

            if (headingBlock.Level < 2)
            {
                return; // Ignore h1 since there's no point including it.
            }
            var document = processor.Document;
            var toc      = document.Where(b => b is TableOfContentsBlock).FirstOrDefault() as TableOfContentsBlock;

            if (toc == null)
            {
                return;
            }

            ContainerBlock parent = toc;

            for (int i = 0; i < headingBlock.Level - 2; i++) // 2 is the minimum level we support, hence -2
            {
                if (!(parent.LastChild is ContainerBlock childContainer))
                {
                    childContainer = new ListItemBlock(block.Parser);
                    parent.Add(childContainer);
                }
                parent = (ContainerBlock)parent.LastChild;
            }

            var headingCopy = new HeadingBlock(block.Parser)
            {
                Column                    = headingBlock.Column,
                HeaderChar                = headingBlock.HeaderChar,
                Inline                    = headingBlock.Inline,
                IsBreakable               = headingBlock.IsBreakable,
                IsOpen                    = headingBlock.IsOpen,
                Level                     = headingBlock.Level,
                Line                      = headingBlock.Line,
                ProcessInlines            = headingBlock.ProcessInlines,
                RemoveAfterProcessInlines = headingBlock.RemoveAfterProcessInlines,
                Span                      = headingBlock.Span
            };

            headingCopy.Lines = new StringLineGroup(headingBlock.Lines.Lines.Length);
            headingCopy.SetAttributes(headingBlock.GetAttributes());
            foreach (var line in headingBlock.Lines.Lines)
            {
                if (line.Slice.Text == null)
                {
                    continue;
                }

                var textCopy     = new StringSlice(line.Slice.Text, line.Slice.Start, line.Slice.End);
                var reffableLine = new StringLine(ref textCopy);
                headingCopy.Lines.Add(ref reffableLine);
            }
            parent.Add(headingCopy);
        }
Пример #8
0
        private static string GetTextFromBlockContainer(ContainerBlock container)
        {
            StringBuilder builder = new StringBuilder();

            GetTextFromBlockContainer(container, builder);
            return(builder.ToString());
        }
Пример #9
0
        /// <summary>
        /// Replaces a <see cref="ProxyTableBlock"/> with a <see cref="ParagraphBlock"/>.
        /// </summary>
        /// <param name="blockProcessor">The <see cref="BlockProcessor"/> processing the <see cref="ProxyTableBlock"/> to undo.</param>
        /// <param name="proxyTableBlock">The <see cref="ProxyTableBlock"/> to undo.</param>
        /// <exception cref="ArgumentNullException">Thrown if <paramref name="blockProcessor"/> is <c>null</c>.</exception>
        /// <exception cref="ArgumentNullException">Thrown if <paramref name="proxyTableBlock"/> is <c>null</c>.</exception>
        protected virtual void Undo(BlockProcessor blockProcessor, ProxyTableBlock proxyTableBlock)
        {
            if (blockProcessor == null)
            {
                throw new ArgumentNullException(nameof(blockProcessor));
            }

            if (proxyTableBlock == null)
            {
                throw new ArgumentNullException(nameof(proxyTableBlock));
            }

            // Discard proxyTableBlock
            ContainerBlock parent = proxyTableBlock.Parent;

            blockProcessor.Discard(proxyTableBlock);

            // Replace with paragraph block
            ParagraphBlockParser parser = blockProcessor.Parsers.FindExact <ParagraphBlockParser>();
            var paragraphBlock          = new ParagraphBlock(parser)
            {
                Lines = proxyTableBlock.Lines,
            };

            parent.Add(paragraphBlock);
            blockProcessor.Open(paragraphBlock);
        }
Пример #10
0
        public void Undo_ReplacesProxyTableBlockWithAParagraphBlock()
        {
            // Arrange
            const string dummyText            = "dummyText";
            var          dummyProxyTableBlock = new ProxyTableBlock(null);

            dummyProxyTableBlock.Lines = new StringLineGroup(dummyText);
            BlockParser    dummyBlockParser = _mockRepository.Create <BlockParser>().Object;
            ContainerBlock dummyParent      = _mockRepository.Create <ContainerBlock>(dummyBlockParser).Object; // Must specify block parser since we're calling ProcessLine later

            dummyParent.Add(dummyProxyTableBlock);                                                              // Assigns dummyParent to dummyProxyTableBlock.Parent
            BlockProcessor dummyBlockProcessor = MarkdigTypesFactory.CreateBlockProcessor();

            dummyBlockProcessor.Open(dummyParent);
            dummyBlockProcessor.Open(dummyProxyTableBlock);
            ExposedFlexiTableBlockParser testSubject = CreateExposedFlexiTableBlockParser();

            // Act
            testSubject.ExposedUndo(dummyBlockProcessor, dummyProxyTableBlock);

            // Assert
            Assert.Single(dummyParent);
            var resultParagraphBlock = dummyParent[0] as ParagraphBlock;

            Assert.NotNull(resultParagraphBlock);
            Assert.Equal(dummyText, resultParagraphBlock.Lines.ToString());
            // Verify that ParagraphBlock remains open
            dummyBlockProcessor.ProcessLine(new StringSlice(dummyText));
            Assert.Equal($"{dummyText}\n{dummyText}", resultParagraphBlock.Lines.ToString());
        }
Пример #11
0
        // Handles closing of FlexiSectionBlocks. A FlexiSectionBlock is closed when another FlexiSectionBlock in the same tree with the same or
        // lower level opens.
        internal virtual void UpdateOpenFlexiSectionBlocks(BlockProcessor processor, FlexiSectionBlock flexiSectionBlock)
        {
            // Since sectioning content roots like blockquotes have their own discrete section trees,
            // we maintain a stack of stacks. Each stack represents the open branch of a tree.
            Stack <Stack <FlexiSectionBlock> > openFlexiSectionBlocks = GetOrCreateOpenFlexiSectionBlocks(processor.Document);

            // Discard stacks for closed branches
            while (openFlexiSectionBlocks.Count > 0)
            {
                // When a sectioning content root is closed, all of its children are closed, so the last section in its branch
                // will be closed. Under no circumstance will the section at the tip of a branch be closed without its ancestors
                // being closed as well.
                if (openFlexiSectionBlocks.Peek().Peek().IsOpen)
                {
                    break;
                }

                openFlexiSectionBlocks.Pop();
            }

            // Find parent container block - processor.CurrentContainer may be closed. processor.CurrentContainer is only updated when
            // BlockProcessor.ProcessNewBlocks calls BlockProcessor.CloseAll, so at this point, processor.CurrentContainer may not be the eventual
            // parent of our new FlexiSectionBlock.
            ContainerBlock parentContainerBlock = processor.CurrentContainer;

            while (!parentContainerBlock.IsOpen) // We will eventually reach the root MarkdownDocument (gauranteed to be open) if all other containers aren't open
            {
                parentContainerBlock = parentContainerBlock.Parent;
            }

            if (!(parentContainerBlock is FlexiSectionBlock)) // parentContainerBlock is a sectioning content root, for example, a blockquote. Create a new stack for a new tree
            {
                var newStack = new Stack <FlexiSectionBlock>();
                newStack.Push(flexiSectionBlock);
                openFlexiSectionBlocks.Push(newStack);
            }
            else
            {
                Stack <FlexiSectionBlock> currentBranch = openFlexiSectionBlocks.Peek(); // If parentContainerBlock is a FlexiSectionBlock, at least 1 branch of open FlexiSectionBlocks exists
                // Close open FlexiSectionBlocks that have the same or higher levels
                FlexiSectionBlock flexiSectionBlockToClose = null;
                while (currentBranch.Count > 0)
                {
                    if (currentBranch.Peek().Level < flexiSectionBlock.Level)
                    {
                        break;
                    }

                    flexiSectionBlockToClose = currentBranch.Pop();
                }
                if (flexiSectionBlockToClose != null)
                {
                    processor.Close(flexiSectionBlockToClose);
                }

                // Add new FlexiSectionBlock to current stack
                currentBranch.Push(flexiSectionBlock);
            }
        }
Пример #12
0
        internal AddBlocksAction(ContainerBlock parent)
            : base(parent.Root)
        {
            Param.CheckNotNull(parent);

            AfterChild = null;
            Parent     = parent;
        }
Пример #13
0
 public static void MoveBlock(ContainerBlock newParent, Block blockToMove)
 {
     using (newParent.Transaction())
     {
         blockToMove.Delete();
         newParent.AppendBlocks(blockToMove);
     }
 }
Пример #14
0
 public static void MoveBlocks(ContainerBlock newParent, IEnumerable <Block> blocksToMove)
 {
     using (newParent.Transaction())
     {
         Delete(blocksToMove);
         newParent.Add(blocksToMove);
     }
 }
Пример #15
0
        internal AddBlocksAction(ContainerBlock parent, Block afterChild)
            : base(afterChild.Root)
        {
            Param.CheckNotNull(afterChild);

            AfterChild = afterChild;
            Parent     = parent;
        }
Пример #16
0
        public static AddBlocksAction AddBlocks(
            ContainerBlock parentBlock,
            IEnumerable <Block> blocksToAdd)
        {
            AddBlocksAction action = new AddBlocksAction(parentBlock);

            action.PrepareBlocks(blocksToAdd);
            return(action);
        }
Пример #17
0
 private void RewriteContainerBlock(ContainerBlock blocks)
 {
     for (var i = 0; i < blocks.Count; i++)
     {
         var block = blocks[i];
         if (block is LeafBlock leafBlock && leafBlock.Inline != null)
         {
             RewriteContainerInline(leafBlock.Inline);
         }
Пример #18
0
        public static AddBlocksAction AddBlock(
            ContainerBlock parentBlock,
            Block toAdd)
        {
            AddBlocksAction action = new AddBlocksAction(parentBlock);

            action.PrepareBlocks(toAdd);
            return(action);
        }
Пример #19
0
		public virtual void VisitContainer(ContainerBlock block)
		{
			foreach (Block child in block.Children)
			{
				ICSharpBlock visitable = child as ICSharpBlock;
				if (visitable != null)
				{
					visitable.AcceptVisitor(this);
				}
			}
		}
Пример #20
0
        public static T FindFirstContainingBlock <T>(Block block)
            where T : class
        {
            ContainerBlock current = block.Parent;

            while (current != null && !(current is T))
            {
                current = current.Parent;
            }
            return(current as T);
        }
Пример #21
0
        }         // proc WriteItems

        public void WriteItems(ContainerBlock block, bool preserveSpaces = false)
        {
            if (block == null)
            {
                throw new ArgumentNullException(nameof(block));
            }

            WriteStartText(preserveSpaces);
            WriteChildren(block);
            WriteEndText();
        }         // proc WriteItems
Пример #22
0
        public static ContainerBlock FindContainingMember(Block block)
        {
            ContainerBlock current = block.Parent;

            while (current != null &&
                   !(current is MethodBlock) &&
                   !(current is PropertyBlock))
            {
                current = current.Parent;
            }
            return(current);
        }
Пример #23
0
        /// <summary>
        /// Writes children with the specified implicit paragraphs setting.
        /// </summary>
        public static HtmlRenderer WriteChildren(this HtmlRenderer htmlRenderer, ContainerBlock containerBlock, bool implicitParagraphs)
        {
            bool initialImplicitParagraph = htmlRenderer.ImplicitParagraph;

            htmlRenderer.ImplicitParagraph = implicitParagraphs;

            htmlRenderer.WriteChildren(containerBlock);

            htmlRenderer.ImplicitParagraph = initialImplicitParagraph;

            return(htmlRenderer);
        }
 private void SetLineNoAttributeOnAllBlocks(ContainerBlock rootBlock)
 {
     foreach (var childBlock in rootBlock)
     {
         if (childBlock is ContainerBlock)
         {
             SetLineNoAttributeOnAllBlocks(childBlock as ContainerBlock);
         }
         var attributes = childBlock.GetAttributes();
         attributes.Id = childBlock.Line.ToString();
         childBlock.SetAttributes(attributes);
     }
 }
Пример #25
0
 public bool UnIndent()
 {
     if (this.Next == null && this.Prev != null)
     {
         ContainerBlock p = this.ParentParent;
         if (p != null && p.Parent != Root)
         {
             this.MoveAfterBlock(p);
             return(true);
         }
     }
     return(false);
 }
Пример #26
0
 public bool TryValidateAncestry(ContainerBlock container, Action <string> logError)
 {
     while (container != null)
     {
         if (container is TripleColonBlock && ((TripleColonBlock)container).Extension.Name == this.Name)
         {
             logError("Zones cannot be nested.");
             return(false);
         }
         container = container.Parent;
     }
     return(true);
 }
        private void VisitContainerBlock(ContainerBlock blocks)
        {
            for (var i = 0; i < blocks.Count; i++)
            {
                var block = blocks[i];
                if (block is ContainerBlock containerBlock)
                {
                    VisitContainerBlock(containerBlock);
                }

                var context = new BlockAggregateContext(blocks);
                Aggregate(context);
            }
        }
Пример #28
0
//		public static CodeBlock FindContainingMember(Block block)
//		{
//			MethodBlock method = FindContainingMethod(block);
//			if (method != null)
//			{
//				return method;
//			}
//
//			PropertyAccessorBlock accessor = FindContainingPropertyAccessor(block);
//			if (accessor != null)
//			{
//				return accessor.ParentProperty;
//			}
//
//			return null;
//		}

        public static ContainerBlock FindContainingControlStructure(Block current)
        {
            ContainerBlock result = FindFirstContainingBlock <ControlStructureBlock>(current);

            if (result == null)
            {
                return(null);
            }
            if (result is DoBlock)
            {
                result = result.Parent as ContainerBlock;
            }
            return(result);
        }
Пример #29
0
 public static void IncreaseHeadingLevel(this ContainerBlock containerBlock, int levelDiff)
 {
     if (levelDiff == 0)
     {
         return;
     }
     foreach (Block child in containerBlock)
     {
         if (child is HeadingBlock headingBlock)
         {
             headingBlock.Level += levelDiff;
         }
     }
 }
Пример #30
0
        public void Validate(Container container)
        {
            var extensionBlocks = ContainerBlock.GetRecursivelyOfType <IExtensionBlock>();
            var context         = new ValidationContext(_renderSettings, Pipeline);

            foreach (var extensionBlock in extensionBlocks)
            {
                if (_blockErrors.ContainsKey(extensionBlock))
                {
                    // don't check for model errors if parsing didn't succeed
                    continue;
                }
                var extensionType = _extensionByBlockType[extensionBlock.GetType()];
                var extension     = (IExtension)container.GetInstance(extensionType);
                var validator     = extension.Validator;
                if (validator == null)
                {
                    continue;
                }
                var     model            = _modelByBlock[extensionBlock];
                IErrors validationResult = validator.Validate(model, context);
                if (validationResult.Errors.Any())
                {
                    _blockErrors.Add(extensionBlock, validationResult);
                }
            }
            var extensionInlines = ContainerBlock.GetInlinesRecursively();

            foreach (var extensionInline in extensionInlines)
            {
                if (_inlineErrors.ContainsKey(extensionInline))
                {
                    // don't check for model errors if parsing didn't succeed
                    continue;
                }
                var extensionType = _extensionByInlineType[extensionInline.GetType()];
                var extension     = (IExtension)container.GetInstance(extensionType);
                var validator     = extension.Validator;
                if (validator == null)
                {
                    continue;
                }
                var model            = _modelByInline[extensionInline];
                var validationResult = validator.Validate(model, context);
                if (validationResult.Errors.Any())
                {
                    _inlineErrors.Add(extensionInline, validationResult);
                }
            }
        }