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); }
/// <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); }
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()); }
public static void MoveBlocks(ContainerBlock newParent, IEnumerable <Block> blocksToMove) { using (newParent.Transaction()) { Delete(blocksToMove); newParent.Add(blocksToMove); } }