/// <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); }
private static void Undo(BlockProcessor processor, GridTableState tableState, Table gridTable) { var parser = processor.Parsers.FindExact <ParagraphBlockParser>(); // Discard the grid table var parent = gridTable.Parent; processor.Discard(gridTable); var paragraphBlock = new ParagraphBlock(parser) { Lines = tableState.Lines, }; parent.Add(paragraphBlock); processor.Open(paragraphBlock); }
public override BlockState TryOpen(BlockProcessor processor) { var paragraphBlock = processor.LastBlock as ParagraphBlock; if (processor.IsCodeIndent || paragraphBlock == null || paragraphBlock.LastLine - processor.LineIndex > 1) { return(BlockState.None); } var startPosition = processor.Start; var column = processor.ColumnBeforeIndent; processor.NextChar(); processor.ParseIndent(); var delta = processor.Column - column; // We expect to have a least if (delta < 4) { // Return back to original position processor.GoToColumn(column); return(BlockState.None); } if (delta > 4) { processor.GoToColumn(column + 4); } var previousParent = paragraphBlock.Parent; var currentDefinitionList = GetCurrentDefinitionList(paragraphBlock, previousParent); processor.Discard(paragraphBlock); // If the paragraph block was not part of the opened blocks, we need to remove it manually from its parent container if (paragraphBlock.Parent != null) { paragraphBlock.Parent.Remove(paragraphBlock); } if (currentDefinitionList == null) { currentDefinitionList = new DefinitionList(this) { Span = new SourceSpan(paragraphBlock.Span.Start, processor.Line.End), Column = paragraphBlock.Column, Line = paragraphBlock.Line, }; previousParent.Add(currentDefinitionList); } var definitionItem = new DefinitionItem(this) { Line = processor.LineIndex, Column = column, Span = new SourceSpan(startPosition, processor.Line.End), OpeningCharacter = processor.CurrentChar, }; for (int i = 0; i < paragraphBlock.Lines.Count; i++) { var line = paragraphBlock.Lines.Lines[i]; var term = new DefinitionTerm(this) { Column = paragraphBlock.Column, Line = line.Line, Span = new SourceSpan(paragraphBlock.Span.Start, paragraphBlock.Span.End), IsOpen = false }; term.AppendLine(ref line.Slice, line.Column, line.Line, line.Position); definitionItem.Add(term); } currentDefinitionList.Add(definitionItem); processor.Open(definitionItem); // Update the end position currentDefinitionList.UpdateSpanEnd(processor.Line.End); return(BlockState.Continue); }
public override BlockState TryContinue(BlockProcessor processor, Block block) { var gridTable = (Table)block; var tableState = (GridTableState)block.GetData(typeof(GridTableState)); // We expect to start at the same //if (processor.Start == tableState.Start) { var columns = tableState.ColumnSlices; foreach (var columnSlice in columns) { columnSlice.PreviousColumnSpan = columnSlice.CurrentColumnSpan; columnSlice.CurrentColumnSpan = 0; } if (processor.CurrentChar == '+') { var result = ParseRowSeparator(processor, tableState, gridTable); if (result != BlockState.None) { return(result); } } else if (processor.CurrentChar == '|') { var line = processor.Line; // | ------------- | ------------ | ---------------------------------------- | // Calculate the colspan for the new row int columnIndex = -1; foreach (var columnSlice in columns) { if (line.PeekCharExtra(columnSlice.Start) == '|') { columnIndex++; } if (columnIndex >= 0) { columns[columnIndex].CurrentColumnSpan++; } } // Check if the colspan of the current row is the same than the previous row bool continueRow = true; foreach (var columnSlice in columns) { if (columnSlice.PreviousColumnSpan != columnSlice.CurrentColumnSpan) { continueRow = false; break; } } // If the current row doesn't continue the previous row (col span are different) // Close the previous row if (!continueRow) { TerminateLastRow(processor, tableState, gridTable, false); } for (int i = 0; i < columns.Count;) { var column = columns[i]; var nextColumnIndex = i + column.CurrentColumnSpan; // If the span is 0, we exit if (nextColumnIndex == i) { break; } var nextColumn = nextColumnIndex < columns.Count ? columns[nextColumnIndex] : null; var sliceForCell = line; sliceForCell.Start = line.Start + column.Start + 1; if (nextColumn != null) { sliceForCell.End = line.Start + nextColumn.Start - 1; } else { var columnEnd = columns[columns.Count - 1].End; // If there is a `|` exactly at the expected end of the table row, we cut the line // otherwise we allow to have the last cell of a row to be open for longer cell content if (line.PeekCharExtra(columnEnd + 1) == '|') { sliceForCell.End = line.Start + columnEnd; } } sliceForCell.TrimEnd(); // Process the content of the cell column.BlockProcessor.LineIndex = processor.LineIndex; column.BlockProcessor.ProcessLine(sliceForCell); // Go to next column i = nextColumnIndex; } return(BlockState.ContinueDiscard); } } TerminateLastRow(processor, tableState, gridTable, true); // If we don't have a row, it means that only the header was valid // So we need to remove the grid table, and create a ParagraphBlock // with the 2 slices if (gridTable.Count == 0) { var parser = processor.Parsers.FindExact <ParagraphBlockParser>(); // Discard the grid table var parent = gridTable.Parent; processor.Discard(gridTable); var paragraphBlock = new ParagraphBlock(parser) { Lines = tableState.Lines, }; parent.Add(paragraphBlock); processor.Open(paragraphBlock); } return(BlockState.Break); }