public override BlockState TryOpen(BlockProcessor processor) { if (processor.IsCodeIndent) { return(BlockState.None); } var column = processor.Column; var sourcePosition = processor.Start; // 5.1 Block quotes // A block quote marker consists of 0-3 spaces of initial indent, plus (a) the character > together with a following space, or (b) a single character > not followed by a space. var quoteChar = processor.CurrentChar; var c = processor.NextChar(); if (c.IsSpaceOrTab()) { processor.NextColumn(); } processor.NewBlocks.Push(new QuoteBlock(this) { QuoteChar = quoteChar, Column = column, Span = new SourceSpan(sourcePosition, processor.Line.End), }); return(BlockState.Continue); }
public override BlockState TryContinue(BlockProcessor processor, Block block) { if (processor.IsCodeIndent) { return(BlockState.None); } var quote = (QuoteBlock)block; var sourcePosition = processor.Start; // 5.1 Block quotes // A block quote marker consists of 0-3 spaces of initial indent, plus (a) the character > together with a following space, or (b) a single character > not followed by a space. var c = processor.CurrentChar; bool hasSpaceAfterQuoteChar = false; if (c != quote.QuoteChar) { if (processor.IsBlankLine) { return(BlockState.BreakDiscard); } else { quote.QuoteLines.Add(new QuoteBlockLine { QuoteChar = false, NewLine = processor.Line.NewLine, }); return(BlockState.None); } } c = processor.NextChar(); // Skip quote marker char if (c == ' ') { processor.NextColumn(); hasSpaceAfterQuoteChar = true; processor.SkipFirstUnwindSpace = true; } else if (c == '\t') { processor.NextColumn(); } var TriviaSpaceBefore = processor.UseTrivia(sourcePosition - 1); StringSlice triviaAfter = StringSlice.Empty; bool wasEmptyLine = false; if (processor.Line.IsEmptyOrWhitespace()) { processor.TriviaStart = processor.Start; triviaAfter = processor.UseTrivia(processor.Line.End); wasEmptyLine = true; } quote.QuoteLines.Add(new QuoteBlockLine { QuoteChar = true, HasSpaceAfterQuoteChar = hasSpaceAfterQuoteChar, TriviaBefore = TriviaSpaceBefore, TriviaAfter = triviaAfter, NewLine = processor.Line.NewLine, }); if (!wasEmptyLine) { processor.TriviaStart = processor.Start; } block.UpdateSpanEnd(processor.Line.End); return(BlockState.Continue); }
private BlockState TryParseListItem(BlockProcessor state, Block block) { // If we have a code indent and we are not in a ListItem, early exit if (!(block is ListItemBlock) && state.IsCodeIndent) { return(BlockState.None); } var currentListItem = block as ListItemBlock; var currentParent = block as ListBlock ?? (ListBlock)currentListItem?.Parent; var initColumnBeforeIndent = state.ColumnBeforeIndent; var initColumn = state.Column; var sourcePosition = state.Start; var sourceEndPosition = state.Line.End; var c = state.CurrentChar; var itemParser = mapItemParsers[c]; bool isOrdered = itemParser is OrderedListItemParser; if (itemParser == null) { return(BlockState.None); } // Try to parse the list item ListInfo listInfo; if (!itemParser.TryParse(state, currentParent?.BulletType ?? '\0', out listInfo)) { // Reset to an a start position state.GoToColumn(initColumn); return(BlockState.None); } // Gets the current character after a succesfull parsing of the list information c = state.CurrentChar; // Item starting with a blank line int columnWidth; // Do we have a blank line right after the bullet? if (c == '\0') { // Use a negative number to store the number of expected chars columnWidth = -(state.Column - initColumnBeforeIndent + 1); } else { if (!c.IsSpaceOrTab()) { state.GoToColumn(initColumn); return(BlockState.None); } // We require at least one char state.NextColumn(); // Parse the following indent state.RestartIndent(); var columnBeforeIndent = state.Column; state.ParseIndent(); if (state.IsCodeIndent) { state.GoToColumn(columnBeforeIndent); } // Number of spaces required for the following content to be part of this list item // If the list item starts with a blank line, the number of spaces // following the list marker doesn't change the required indentation columnWidth = (state.IsBlankLine ? columnBeforeIndent : state.Column) - initColumnBeforeIndent; } var newListItem = new ListItemBlock(this) { Column = initColumn, ColumnWidth = columnWidth, Span = new SourceSpan(sourcePosition, sourceEndPosition) }; state.NewBlocks.Push(newListItem); if (currentParent != null) { // If we have a new list item, close the previous one if (currentListItem != null) { state.Close(currentListItem); } // Reset the list if it is a new list or a new type of bullet if (currentParent.IsOrdered != isOrdered || currentParent.OrderedDelimiter != listInfo.OrderedDelimiter || currentParent.BulletType != listInfo.BulletType) { state.Close(currentParent); currentParent = null; } } if (currentParent == null) { var newList = new ListBlock(this) { Column = initColumn, Span = new SourceSpan(sourcePosition, sourceEndPosition), IsOrdered = isOrdered, BulletType = listInfo.BulletType, OrderedDelimiter = listInfo.OrderedDelimiter, DefaultOrderedStart = listInfo.DefaultOrderedStart, OrderedStart = listInfo.OrderedStart, }; state.NewBlocks.Push(newList); } return(BlockState.Continue); }
public override BlockState TryOpen(BlockProcessor processor) { if (processor.IsCodeIndent) { return(BlockState.None); } var sourcePosition = processor.Start; // 5.1 Block quotes // A block quote marker consists of 0-3 spaces of initial indent, plus (a) the character > together with a following space, or (b) a single character > not followed by a space. var quoteChar = processor.CurrentChar; var column = processor.Column; var c = processor.NextChar(); var quoteBlock = new QuoteBlock(this) { QuoteChar = quoteChar, Column = column, Span = new SourceSpan(sourcePosition, processor.Line.End), LinesBefore = processor.UseLinesBefore() }; bool hasSpaceAfterQuoteChar = false; if (c == ' ') { processor.NextColumn(); hasSpaceAfterQuoteChar = true; processor.SkipFirstUnwindSpace = true; } else if (c == '\t') { processor.NextColumn(); } var triviaBefore = processor.UseTrivia(sourcePosition - 1); StringSlice triviaAfter = StringSlice.Empty; bool wasEmptyLine = false; if (processor.Line.IsEmptyOrWhitespace()) { processor.TriviaStart = processor.Start; triviaAfter = processor.UseTrivia(processor.Line.End); wasEmptyLine = true; } quoteBlock.QuoteLines.Add(new QuoteBlockLine { TriviaBefore = triviaBefore, TriviaAfter = triviaAfter, QuoteChar = true, HasSpaceAfterQuoteChar = hasSpaceAfterQuoteChar, NewLine = processor.Line.NewLine, }); processor.NewBlocks.Push(quoteBlock); if (!wasEmptyLine) { processor.TriviaStart = processor.Start; } return(BlockState.Continue); }