Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cleanup ListBlockParser #422

Merged
merged 2 commits into from
Apr 18, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 35 additions & 57 deletions src/Markdig/Parsers/ListBlockParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,8 @@ public override BlockState TryContinue(BlockProcessor processor, Block block)
// TODO: Check with specs, it is not clear that list marker or bullet marker must be followed by at least 1 space

// If we have already a ListItemBlock, we are going to try to append to it
var listItem = block as ListItemBlock;
result = BlockState.None;
if (listItem != null)
if (block is ListItemBlock listItem)
{
result = TryContinueListItem(processor, listItem);
}
Expand All @@ -123,12 +122,9 @@ private BlockState TryContinueListItem(BlockProcessor state, ListItemBlock listI
// Allow all blanks lines if the last block is a fenced code block
// Allow 1 blank line inside a list
// If > 1 blank line, terminate this list
var isBlankLine = state.IsBlankLine;

var isCurrentBlockBreakable = state.CurrentBlock != null && state.CurrentBlock.IsBreakable;
if (isBlankLine)
if (state.IsBlankLine)
{
if (isCurrentBlockBreakable)
if (state.CurrentBlock != null && state.CurrentBlock.IsBreakable)
{
if (!(state.NextContinue is ListBlock))
{
Expand Down Expand Up @@ -195,21 +191,21 @@ private BlockState TryParseListItem(BlockProcessor state, Block block)

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))
if (!itemParser.TryParse(state, currentParent?.BulletType ?? '\0', out ListInfo listInfo))
{
// Reset to an a start position
state.GoToColumn(initColumn);
return BlockState.None;
}

bool isOrdered = itemParser is OrderedListItemParser;

// Gets the current character after a successful parsing of the list information
c = state.CurrentChar;

Expand Down Expand Up @@ -251,11 +247,10 @@ private BlockState TryParseListItem(BlockProcessor state, Block block)
// Starts/continue the list unless:
// - an empty list item follows a paragraph
// - an ordered list is not starting by '1'
var isPreviousParagraph = (block ?? state.LastBlock) is ParagraphBlock;
if (isPreviousParagraph)
if ((block ?? state.LastBlock) is ParagraphBlock previousParagraph)
{
var isOpen = state.IsOpen(block ?? state.LastBlock);
if (state.IsBlankLine || (isOpen && listInfo.BulletType == '1' && listInfo.OrderedStart != "1"))
if (state.IsBlankLine ||
state.IsOpen(previousParagraph) && listInfo.BulletType == '1' && listInfo.OrderedStart != "1")
{
state.GoToColumn(initColumn);
return BlockState.None;
Expand Down Expand Up @@ -310,64 +305,47 @@ private BlockState TryParseListItem(BlockProcessor state, Block block)

public override bool Close(BlockProcessor processor, Block blockToClose)
{
var listBlock = blockToClose as ListBlock;

// Process only if we have blank lines
if (listBlock == null || listBlock.CountAllBlankLines <= 0)
if (blockToClose is ListBlock listBlock && listBlock.CountAllBlankLines > 0)
{
return true;
}
if (listBlock.Parent is ListItemBlock parentListItemBlock &&
listBlock.LastChild is ListItemBlock lastListItem &&
lastListItem.LastChild is BlankLineBlock)
{
// Inform the outer list that we have a blank line
var parentList = (ListBlock)parentListItemBlock.Parent;

// TODO: This code is UGLY and WAY TOO LONG, simplify!
bool isLastListItem = true;
for (int listIndex = listBlock.Count - 1; listIndex >= 0; listIndex--)
{
var block = listBlock[listIndex];
var listItem = (ListItemBlock) block;
bool isLastElement = true;
for (int i = listItem.Count - 1; i >= 0; i--)
parentList.CountAllBlankLines++;
parentListItemBlock.Add(new BlankLineBlock());
}

for (int listIndex = listBlock.Count - 1; listIndex >= 0; listIndex--)
{
var item = listItem[i];
if (item is BlankLineBlock)
{
if ((isLastElement && listIndex < listBlock.Count - 1) || (listItem.Count > 2 && (i > 0 && i < (listItem.Count - 1))))
{
listBlock.IsLoose = true;
}
var listItem = (ListItemBlock)listBlock[listIndex];

if (isLastElement && isLastListItem)
for (int i = listItem.Count - 1; i >= 0; i--)
{
if (listItem[i] is BlankLineBlock)
{
// Inform the outer list that we have a blank line
var parentListItemBlock = listBlock.Parent as ListItemBlock;
if (parentListItemBlock != null)
if (i == listItem.Count - 1 ? listIndex < listBlock.Count - 1 : i > 0)
{
var parentList = (ListBlock) parentListItemBlock.Parent;

parentList.CountAllBlankLines++;
parentListItemBlock.Add(new BlankLineBlock());
listBlock.IsLoose = true;
}
}

listItem.RemoveAt(i);
listItem.RemoveAt(i);

// If we have remove all blank lines, we can exit
listBlock.CountAllBlankLines--;
if (listBlock.CountAllBlankLines == 0)
{
break;
// If we have removed all blank lines, we can exit
listBlock.CountAllBlankLines--;
if (listBlock.CountAllBlankLines == 0)
{
goto done;
}
}
}
isLastElement = false;
}
isLastListItem = false;
}

//// Update end-position for the list
//if (listBlock.Count > 0)
//{
// listBlock.Span.End = listBlock[listBlock.Count - 1].Span.End;
//}

done:
return true;
}
}
Expand Down