in src/Elastic.Markdown/Myst/Comments/CommentBlockParser.cs [56:151]
public override BlockState TryOpen(BlockProcessor processor)
{
// If we are in a CodeIndent, early exit
if (processor.IsCodeIndent)
return BlockState.None;
var column = processor.Column;
var line = processor.Line;
var sourcePosition = line.Start;
var c = line.CurrentChar;
var matchingChar = c;
Debug.Assert(MaxLeadingCount > 0);
var leadingCount = 0;
while (c != '\0' && leadingCount <= MaxLeadingCount)
{
if (c != matchingChar)
break;
c = processor.NextChar();
leadingCount++;
}
// A space is required after leading %
if (leadingCount > 0 && leadingCount <= MaxLeadingCount && (c.IsSpaceOrTab() || c == '\0'))
{
if (processor.TrackTrivia && c.IsSpaceOrTab())
_ = processor.NextChar();
// Move to the content
var headingBlock = new CommentBlock(this)
{
CommentChar = matchingChar,
Level = leadingCount,
Column = column,
Span = { Start = sourcePosition },
};
if (processor.TrackTrivia)
{
headingBlock.TriviaBefore = processor.UseTrivia(sourcePosition - 1);
var linesBefore = processor.LinesBefore;
processor.LinesBefore = null;
headingBlock.LinesBefore = linesBefore;
headingBlock.NewLine = processor.Line.NewLine;
}
else
processor.GoToColumn(column + leadingCount + 1);
processor.NewBlocks.Push(headingBlock);
// The optional closing sequence of #s must be preceded by a space and may be followed by spaces only.
var endState = 0;
var countClosingTags = 0;
for (var i = processor.Line.End;
i >= processor.Line.Start - 1;
i--) // Go up to Start - 1 in order to match the space after the first ###
{
c = processor.Line.Text[i];
if (endState == 0)
{
if (c.IsSpaceOrTab())
continue;
endState = 1;
}
if (endState == 1)
{
if (c == matchingChar)
{
countClosingTags++;
continue;
}
if (countClosingTags > 0)
{
if (c.IsSpaceOrTab())
processor.Line.End = i - 1;
}
break;
}
}
// Set up the source end position of this element
headingBlock.Span.End = processor.Line.End;
// We expect a single line, so don't continue
return BlockState.Break;
}
// Else we don't have an header
processor.Line.Start = sourcePosition;
processor.Column = column;
return BlockState.None;
}