Example #1
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);
        }
Example #2
0
        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);
        }
Example #3
0
        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);
        }
Example #4
0
        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);
        }