Example #1
0
        public override BlockState TryOpen(BlockProcessor processor)
        {
            var paragraphBlock = processor.LastBlock as ParagraphBlock;

            if (processor.IsCodeIndent || paragraphBlock is 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 is 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, processor.TrackTrivia);
                definitionItem.Add(term);
            }
            currentDefinitionList.Add(definitionItem);
            processor.Open(definitionItem);

            // Update the end position
            currentDefinitionList.UpdateSpanEnd(processor.Line.End);

            return(BlockState.Continue);
        }
Example #2
0
        public override BlockState TryContinue(BlockProcessor processor, Block block)
        {
            var definitionItem = (DefinitionItem)block;

            if (processor.IsCodeIndent)
            {
                processor.GoToCodeIndent();
                return(BlockState.Continue);
            }

            var list          = (DefinitionList)definitionItem.Parent !;
            var lastBlankLine = definitionItem.LastChild as BlankLineBlock;

            // Check if we have another definition list
            if (Array.IndexOf(OpeningCharacters !, processor.CurrentChar) >= 0)
            {
                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)
                {
                    // Remove the blankline before breaking this definition item
                    if (lastBlankLine != null)
                    {
                        definitionItem.RemoveAt(definitionItem.Count - 1);
                    }

                    list.Span.End = list.LastChild !.Span.End;
                    return(BlockState.None);
                }

                if (delta > 4)
                {
                    processor.GoToColumn(column + 4);
                }

                processor.Close(definitionItem);
                var nextDefinitionItem = new DefinitionItem(this)
                {
                    Span             = new SourceSpan(startPosition, processor.Line.End),
                    Line             = processor.LineIndex,
                    Column           = processor.Column,
                    OpeningCharacter = processor.CurrentChar,
                };
                list.Add(nextDefinitionItem);
                processor.Open(nextDefinitionItem);

                return(BlockState.Continue);
            }

            var isBreakable = definitionItem.LastChild?.IsBreakable ?? true;

            if (processor.IsBlankLine)
            {
                if (lastBlankLine is null && isBreakable)
                {
                    definitionItem.Add(new BlankLineBlock());
                }
                return(isBreakable ? BlockState.ContinueDiscard : BlockState.Continue);
            }

            var paragraphBlock = definitionItem.LastChild as ParagraphBlock;

            if (lastBlankLine is null && paragraphBlock != null)
            {
                return(BlockState.Continue);
            }

            // Remove the blankline before breaking this definition item
            if (lastBlankLine != null)
            {
                definitionItem.RemoveAt(definitionItem.Count - 1);
            }

            list.Span.End = list.LastChild !.Span.End;
            return(BlockState.Break);
        }