/// <summary>
        /// Continues a <see cref="ProxyTableBlock"/> if the current line is a content line or a separator line.
        /// </summary>
        /// <param name="blockProcessor">The <see cref="BlockProcessor"/> processing the <see cref="ProxyTableBlock"/> to try continuing.</param>
        /// <param name="block">The <see cref="ProxyTableBlock"/> to try continuing.</param>
        /// <returns>
        /// <see cref="BlockState.Break"/> if the current line does not start with '|' or '+'. This closes the <see cref="ProxyTableBlock"/>.
        /// <see cref="BlockState.Break"/> if the current line starts with '|' or '+' but is not a content line or separator line. The <see cref="ProxyTableBlock"/> is replaced with a paragraph block.
        /// <see cref="BlockState.ContinueDiscard"/> if the <see cref="ProxyTableBlock"/> remains open.
        /// </returns>
        protected override BlockState TryContinueBlock(BlockProcessor blockProcessor, ProxyTableBlock block)
        {
            // Parse line
            bool undo;

            if (blockProcessor.CurrentChar == '|') // Content line
            {
                undo = !TryParseContentLine(blockProcessor, block);
            }
            else if (blockProcessor.CurrentChar == '+') // Row separator line
            {
                undo = !TryParseSeparatorLine(blockProcessor.Line, block);
            }
            else // No longer in table
            {
                return(BlockState.Break);
            }

            if (undo)
            {
                Undo(blockProcessor, block);
                return(BlockState.Break);
            }

            // Update span end
            block.UpdateSpanEnd(blockProcessor.Line.End);

            // Store current line in case the grid FlexiTableBlock is invalid
            block.Lines.Add(blockProcessor.Line);

            return(BlockState.ContinueDiscard);
        }
        /// <summary>
        /// Continues a <see cref="ProxyTableBlock"/> if the current line is a column definitions line or a row line.
        /// </summary>
        /// <param name="blockProcessor">The <see cref="BlockProcessor"/> for the <see cref="ProxyTableBlock"/> to try continuing.</param>
        /// <param name="block">The <see cref="ProxyTableBlock"/> to try continuing.</param>
        /// <returns>
        /// <see cref="BlockState.Break"/> if the current line does not start with '|'. This closes the <see cref="ProxyTableBlock"/>.
        /// <see cref="BlockState.Break"/> if the current line starts with '|' but is not a column definitions line or row line. The <see cref="ProxyTableBlock"/> is replaced with a paragraph block.
        /// <see cref="BlockState.ContinueDiscard"/> if the <see cref="ProxyTableBlock"/> remains open.
        /// </returns>
        protected override BlockState TryContinueBlock(BlockProcessor blockProcessor, ProxyTableBlock block)
        {
            if (blockProcessor.CurrentChar != '|') // No longer in table
            {
                return(BlockState.Break);
            }

            // Parse line
            StringSlice             line       = blockProcessor.Line;
            List <Row>              rows       = block.Rows;
            bool                    undo       = true;
            int                     numColumns = block.NumColumns;
            List <ColumnDefinition> columnDefinitions;

            if (block.ColumnDefinitions == null &&
                (columnDefinitions = TryParseColumnDefinitionsLine(line, '|', numColumns)) != null)
            {
                undo = false;
                block.ColumnDefinitions = columnDefinitions;

                foreach (Row headerRow in rows)
                {
                    headerRow.IsHeaderRow = true;
                }
            }

            Row row;

            if (undo && (row = TryParseRowLine(blockProcessor, rows.Count, numColumns)) != null)
            {
                undo = false;
                rows.Add(row);
            }

            if (undo)
            {
                Undo(blockProcessor, block);

                return(BlockState.Break);
            }

            // Update span end
            block.UpdateSpanEnd(line.End);

            // Store current line in case the grid FlexiTableBlock is invalid
            block.Lines.Add(line);

            return(BlockState.ContinueDiscard);
        }